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

📄 zmodemr.c

📁 本source code 為s3c4510的bootloader
💻 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: * *	ZmRInit(ZModem *info) *		Initiate a connection * *	ZmRAbort(ZModem *info) *		abort transfer * * all functions return 0 on success, 1 on failure * * *	Edward A. Falk * *	January, 1995 * * * **********/#include "zmodem.h"#include "crctab.h"// static functions definition ///////////////////////////////////////////////static int  ZmGotSinit( ZModem *info );static int  ZmGotFile( ZModem *info );static int  ZmRequestFile( ZModem *info, u_long crc );static void ZmParseFileName( ZModem *info, char *fileinfo );static int  ZmGotFileCrc( ZModem *info );static int  ZmGotData( ZModem *info );static int  ZmFileError( ZModem *info, int type, int data );static int  ZmGotEof( ZModem *info );static int  ZmGotFin( ZModem *info );static int  ZmGotFreecnt( ZModem *info );static int  ZmProcessPacket( ZModem *info );static int  ZmRejectPacket( ZModem *info );static int  ZmAcceptPacket( ZModem *info );static int  ZmCalcCrc( u_char *str, int len );//extern	int	errno ;static	u_char	ZmZeros[4] = {0,0,0,0} ;int ZmRInit(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;/* set buffer pointer to allocation buffer */ info->buffer = info->bufferalloc; 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 ZmRcv() to check the input stream first.	 * If nothing found, a ZRINIT will be sent immediately.	 */ info->timeout = 0 ;#ifdef ZMODEMLOG zmodemlog("ZmRInit[%s]: flush input, new state = RStart\n",    ZmSname(info)) ;#endif 								// ZMODEMLOG return(0);}int YmodemRInit(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 )  {/* set buffer pointer to allocation buffer */    info->buffer = info->bufferalloc;  } info->state = YRStart ; info->packetCount = -1 ; info->timeoutCount = 0 ; info->timeout = 10 ; info->offset = 0 ; ZIFlush(info) ; return(ZXmitStr((u_char *)"C", 1, info));}		/* sent ZRINIT, waiting for ZSINIT or ZFILE */	StateTable	RStartOps[] = {	  {ZSINIT,ZmGotSinit,0,1,RSinitWait},	/* SINIT, wait for attn str */	  {ZFILE,ZmGotFile,0,0,RFileName},	/* FILE, wait for filename */	  {ZRQINIT,ZmSendRinit,0,1,RStart},	/* sender confused, resend */	  {ZFIN,ZmGotFin,1,0,RFinish},		/* sender shutting down */	  {ZNAK,ZmSendRinit,1,0,RStart},		/* RINIT was bad, resend */#ifdef	TODO	  {ZCOMPL,f,1,1,s},#endif	/* TODO */	  {ZFREECNT,ZmGotFreecnt,0,0,RStart},	/* sender wants free space */	  {ZCOMMAND,ZmGotCommand,0,0,CommandData}, /* sender wants command */	  {ZSTDERR,ZmGotStderr,0,0,StderrData},	/* sender wants to send msg */	  {99,ZmZPF,0,0,RStart},			/* anything else is an error */	} ;	StateTable	RSinitWaitOps[] = {	/* waiting for data */	  {99,ZmZPF,0,0,RSinitWait},	} ;	StateTable	RFileNameOps[] = {	/* waiting for file name */	  {99,ZmZPF,0,0,RFileName},	} ;	StateTable	RCrcOps[] = {		/* waiting for CRC */	  {ZCRC,ZmGotFileCrc,0,0,RFile},		  /* sender sent it */	  {ZNAK,ZmResendCrcReq,0,0,RCrc},		  /* ZCRC was bad, resend */	  {ZRQINIT,ZmSendRinit,1,1,RStart},	  /* sender confused, restart */	  {ZFIN,ZmGotFin,1,1,RFinish},		  /* sender signing off */	  {99,ZmZPF,0,0,RCrc},	} ;	StateTable	RFileOps[] = {		/* waiting for ZDATA */	  {ZDATA,ZmGotData,0,0,RData},		  /* got it */	  {ZNAK,ZmResendRpos,0,0,RFile},		  /* ZRPOS was bad, resend */	  {ZEOF,ZmGotEof,0,0,RStart},		  /* end of file */	  {ZRQINIT,ZmSendRinit,1,1,RStart},	  /* sender confused, restart */	  {ZFILE,ZmResendRpos,0,0,RFile},		  /* ZRPOS was bad, resend */	  {ZFIN,ZmGotFin,1,1,RFinish},		  /* sender signing off */	  {99,ZmZPF,0,0,RFile},	} ;	/* waiting for data, but a packet could possibly arrive due	 * to error recovery or something	 */	StateTable	RDataOps[] = {	  {ZRQINIT,ZmSendRinit,1,1,RStart},	/* sender confused, restart */	  {ZFILE,ZmGotFile,0,1,RFileName},	/* start a new file (??) */	  {ZNAK,ZmResendRpos,1,1,RFile},		/* ZRPOS was bad, resend */	  {ZFIN,ZmGotFin,1,1,RFinish},		/* sender signing off */	  {ZDATA,ZmGotData,0,1,RData},		/* file data follows */	  {ZEOF,ZmGotEof,1,1,RStart},		/* end of file */	  {99,ZmZPF,0,0,RData},	} ;	/* here if we've sent ZFERR or ZABORT.  Waiting for ZFIN */	StateTable	RFinishOps[] = {	  {ZRQINIT,ZmSendRinit,1,1,RStart},	/* sender confused, restart */	  {ZFILE,ZmGotFile,1,1,RFileName},	/* start a new file */	  {ZNAK,ZmGotFin,1,1,RFinish},		/* resend ZFIN */	  {ZFIN,ZmGotFin,1,1,RFinish},		/* sender signing off */	  {99,ZmZPF,0,0,RFinish},	} ;extern	char	*hdrnames[] ;/* RECEIVE-RELATED STUFF BELOW HERE *//* resend ZRINIT header in response to ZRQINIT or ZNAK header */int ZmSendRinit( ZModem *info ){ u_char	dbuf[4] ;#ifdef	COMMENT if( info->timeoutCount >= 5 )	  /* TODO: switch to Ymodem */#endif	/* COMMENT */#ifdef ZMODEMLOG zmodemlog("SendRinit[%s]: send ZRINIT\n", ZmSname(info)) ;#endif 								// ZMODEMLOG 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	int ZmGotSinit( ZModem *info ){#ifdef ZMODEMLOG	zmodemlog("GotSinit[%s]: call dataSetup\n", ZmSname(info)) ;#endif 								// ZMODEMLOG	info->zsinitflags = info->hdrData[4] ;	info->escCtrl = info->zsinitflags & TESCCTL ;	info->escHibit = info->zsinitflags & TESC8 ;	ZFlowControl(1, info) ;	return ZmDataSetup(info) ;}	/* received rest of ZSINIT packet */int ZmGotSinitData( ZModem *info, int crcGood ){ info->InputState = Idle; info->chrCount=0 ; info->state = RStart ;#ifdef ZMODEMLOG zmodemlog("GotSinitData[%s]: crcGood=%d\n", ZmSname(info), crcGood) ;#endif 								// ZMODEMLOG if( !crcGood )  {   return ZXmitHdrHex(ZNAK, ZmZeros, info) ;  } info->attn = NULL; if(info->buffer[0] != '\0' )  {   int pos;				/* buffer position */   info->attn = info->attnbuf;		/* set attn pointer to buffer */   pos = 0;				/* start position */   while(1)    {     if(pos + 1 >= sizeof(info->attnbuf))      {       info->attnbuf[pos] = '\0';	/* terminating character */       break;      }     info->attnbuf[pos] = *(info->buffer + pos);     if(info->attnbuf[pos] == '\0')      {       break;      } //      pos++;    }  } return(ZXmitHdrHex(ZACK, ZEnc4(SerialNo), info));}	/* got ZFILE.  Cache flags and set up to receive filename */static	int ZmGotFile( ZModem *info ){#ifdef ZMODEMLOG	zmodemlog("GotFile[%s]: call dataSetup\n", ZmSname(info)) ;#endif 								// ZMODEMLOG	info->errCount = 0 ;	info->f0 = info->hdrData[4] ;	info->f1 = info->hdrData[3] ;	info->f2 = info->hdrData[2] ;	info->f3 = info->hdrData[1] ;	return ZmDataSetup(info) ;}	/* utility: see if ZOpenFile wants this file, and if	 * so, request it from sender.	 */static	int ZmRequestFile( ZModem *info, u_long crc ){/* open file in write mode (last parameter 1) */ info->file = ZOpenFile((char *)info->buffer, crc, info, 1); if( info->file == NULL )   {#ifdef ZMODEMLOG   zmodemlog("requestFile[%s]: send ZSKIP\n", ZmSname(info)) ;#endif 								// ZMODEMLOG   info->state = RStart ;   ZStatus(FileSkip, 0, info->filename) ;   return ZXmitHdrHex(ZSKIP, ZmZeros, info) ;  } else   {#ifdef ZMODEMLOG   zmodemlog("ZmRequestFile[%s]: send ZRPOS(%ld)\n",    ZmSname(info), info->offset) ;#endif 								// ZMODEMLOG   info->offset = info->f0 == ZCRESUM ? ZFileTell(info->file, info) : 0 ;   info->state = RFile;   ZStatus(FileBegin, 0, info->filename) ;   return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info) ;  }}/* read long from string */static  long ZmGetLong(char * buf, int * pos, int radix){ long val;				/* return value */  if(buf == 0 || pos == 0)  {   return(0);  }  /* skeep leading zeros */  while(*(buf + *pos) == ' ') { (*pos) += 1; }  if(*(buf + *pos) == '\0')  {   return(0);  } // val = 0;				/* start return value */ while(1)  {   u_char ch;				   ch = *(buf + *pos); 			/* read character from buffer */       if(radix == 10)    {/* decimal */     if(ch >= '0' && ch <= '9')      {       val = val * 10 + (ch - '0');      }     else      {       break;      }    }   else   if(radix ==  8)    {/* octal */     if(ch >= '0' && ch <= '7')      {       val = (val << 3) | (ch - '0');      }     else      {       break;      }    }              else   if(radix == 16)    {/* hexadecimal */     if(ch >= '0' && ch <= '9')      {       val = (val << 4) | (ch - '0');            }     else     if(ch >= 'a' && ch <= 'f')      {       val = (val << 4) | (10 + (ch - 'a'));            }     else     if(ch >= 'A' && ch <= 'F')      {       val = (val << 4) | (10 + (ch - 'A'));      }     else      {       break;      }    }//    (*pos) += 1;				/* move to next position */  }//  return(val);}/* parse filename info. */static	void ZmParseFileName( ZModem *info, char *fileinfo ){ int serial = 0; int pos; info->len      = 0; info->mode     = 0; info->filesRem = 0; info->bytesRem = 0; info->fileType = 0;//  info->filename = info->filenamebuf;//  pos = 0; while(*(fileinfo + pos) != '\0')  {   if(pos < sizeof(info->filenamebuf))    {     info->filenamebuf[pos] = *(fileinfo+pos);    }   pos++;   } if(pos >= sizeof(info->filenamebuf))  {   info->filenamebuf[sizeof(info->filenamebuf) - 1] = '\0';  } else  {   info->filenamebuf[pos] = '\0';  }//  pos += 1;				/* skip terminating null */ info->len 	= ZmGetLong(fileinfo, & pos, 10); /* %d */

⌨️ 快捷键说明

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