📄 zmodemt.c
字号:
#ifndef lintstatic const char rcsid[] = "$Id: zmodemt.c,v 1.1.1.1 2001/03/08 00:01:48 efalk Exp $" ;#endif/* * Copyright (c) 1995 by Edward A. Falk *//********** * * * @@@@@ @ @ @@@ @@@@ @@@@@ @ @ @@@@@ * @ @@ @@ @ @ @ @ @ @@ @@ @ * @ @ @ @ @ @ @ @ @@@ @ @ @ @ * @ @ @ @ @ @ @ @ @ @ @ @ @ * @@@@@ @ @ @ @@@ @@@@ @@@@@ @ @ @ @ * * ZMODEMT - transmit side of zmodem protocol * * transmit side of zmodem protocol * * Caller sets flags defined in zmodem.h as appropriate. * (default is basic zmodem) * * functions: * * ZmTInit(ZModem *info) * YmTInit(ZModem *info) * XmTInit(ZModem *info) * Initiate a connection * * ZmTFile(char *filename, u_char flags[4], ZModem *info) * Initiate a file transfer. Flags are as specified * under "ZCBIN" in zmodem.h * * ZmTFinish(ZModem *info) * last file * * ZmTAbort(ZModem *info) * abort transfer * * all functions return 0 on success, 1 on abort * * * Edward A. Falk * * January, 1995 * * * **********/#include "zmodem.h"#include "crctab.h"// static function definition ////////////////////////////////////////////////static int ZmSendFilename(ZModem *info);static int ZmGotRinit( ZModem *info );static int ZmSendZSInit( ZModem *info );static int ZmSendFileCrc( ZModem *info );static int ZmStartFileData( ZModem *info );static int ZmSendFileData( ZModem *info );static int ZmGotSendAck( ZModem *info );static int ZmGotSendDoneAck( ZModem *info );static int ZmGotSendNak( ZModem *info );static int ZmSkipFile( ZModem *info );static int ZmGotSendPos( ZModem *info );static int ZmGotSendWaitAck( ZModem *info );static int ZmResendEof( ZModem *info );static int ZmOverAndOut( ZModem *info );static int YXmitData( u_char *buffer, int len, ZModem *info );static int YSendFilename( ZModem *info );static int YSendData( ZModem *info );static int YSendFin( ZModem *info );static u_char zeros[4] = {0,0,0,0} ; /* called by user to establish protocol */int ZmTInit( ZModem *info ){ int err ; int i ; info->state = TStart ; info->Protocol = ZMODEM; info->crc32 = 0 ; info->packetCount = 0 ; info->errCount = 0 ; info->escCtrl = info->escHibit = info->atSign = info->escape = 0 ; info->InputState = Idle; info->canCount = info->chrCount = 0 ; info->windowCount = 0 ; info->filename = NULL ; info->bufsize = 0 ; info->interrupt = 0 ; info->waitflag = 0 ; if( info->packetsize == 0 ) { info->packetsize = 256 ; }/* we won't be receiving much data, pick a reasonable buffer * size (largest packet will do) */ i = info->packetsize * 2; if( i < 1024 ) i = 1024; if( i > sizeof(info->bufferalloc) ) { i = sizeof(info->bufferalloc); info->packetsize = i / 2; } info->buffer = info->bufferalloc; ZIFlush(info) ; /* optional: send "rz\r" to remote end */ if( DoInitRZ ) { err = ZXmitStr((u_char *)"rz\r", 3, info); if(err) return(err); }/* nudge receiver */ err = ZXmitHdr(ZRQINIT, ZHEX, zeros, info); if(err) { return err ; } info->timeout = 60 ;#ifdef ZMODEMLOG zmodemlog("ZmTInit[%s]: sent ZRQINIT\n", ZmSname(info)) ;#endif // ZMODEMLOG return(0);}/* called by user to establish Ymodem protocol */int YmodemTInit( ZModem *info ){ info->state = YTStart; info->Protocol = YMODEM; info->errCount = 0 ; info->InputState = Ysend; info->canCount = info->chrCount = 0 ; info->windowCount = 0 ; info->filename = NULL ; if( info->packetsize != 1024 ) { info->packetsize = 128 ; } info->buffer = info->bufferalloc; ZIFlush(info) ; ZFlowControl(0, info) ; info->timeout = 60 ; return(0);}/* called by user to establish Xmodem protocol */int XmodemTInit( ZModem *info ){ (void) YmodemTInit(info) ; info->Protocol = XMODEM; return 0 ;}/* called by user to begin transmission of a file */int ZmTFile(char * file, char *rfile, u_int f0, u_int f1, u_int f2, u_int f3, int filesRem, int bytesRem, ZModem *info){ if( file == NULL) { return(ZmErrCantOpen); } info->file = ZOpenFile(file, 0,info, 0); /* open in read mode */ if(info->file == NULL) { return(ZmErrCantOpen); } info->fileEof = 0 ; info->filename = file ; info->rfilename = (rfile != NULL) ? rfile : (char *) "noname" ; info->filesRem = filesRem ; info->bytesRem = bytesRem ; info->fileFlags[3] = f0 ; info->fileFlags[2] = f1 ; info->fileFlags[1] = f2 ; info->fileFlags[0] = f3 ; info->offset = info->lastOffset = 0 ; info->len = info->date = info->fileType = info->mode = 0 ; if( info->filename != NULL ) { int len; int date; int mode; if(ZFileStat(info->filename, & len, & date, & mode) == 0 ) { info->len = len; info->date = date; info->fileType = 0 ; info->mode = (mode&0777)|0100000 ; } } if( info->Protocol == XMODEM ) return YSendData(info) ; if( info->Protocol == YMODEM ) return YSendFilename(info) ; info->state = FileWait ;#ifdef ZMODEMLOG zmodemlog("ZmTFile[%s]: send ZFILE(%s)\n", ZmSname(info), info->rfilename) ;#endif // ZMODEMLOG return(ZmSendFilename(info));}/* put long to buffer buf = buffer pos = current position size = sizeof buffer val = printed value radix = 8/10/16*/ static int ZmPutStr(u_char * buf, int * pos, int size, const char * str){ if(buf == 0 || pos == 0 || str == 0) { return(0); } while(1) { if(*pos + 1 >= size) { *(buf + (size - 1)) = '\0'; return(1); } // *(buf + *pos) = *str; if(*str++ == '\0') { return(1); } *pos += 1; }}static int ZmPutLong(u_char * buf, int * pos, int size, long val, int radix){ u_char dig[24]; // temp buffer int num; // position in temp buffer// if( buf == 0 || // invalid buffer pointer pos == 0 // invalid buffer position ) { return(0); } if(val < 0) {// if(*pos < size) { *(buf + *pos) = '-'; // *pos += 1; } // val *= -1; } else if(val == 0) { if(*pos < size) { *(buf + *pos) = '0'; *pos += 1; } if(*pos < size) { *(buf + *pos) = '\0'; } else { *(buf + (size - 1)) = '\0'; }// return(1); }// num = 0; while(val != 0 && num < 24) { u_char ch; if(radix == 10) { ch = '0' + (val % 10); val /= 10; // } else if(radix == 8) { ch = '0' + (val & 0x7); val >>= 3; // } else if(radix == 16) { ch = (val & 0xF); if(ch <= 9) { ch += '0'; // } else { ch = 'a' + (ch - 10); // }// val >>= 4; } dig[num++] = ch; } while(--num >= 0) { if(*pos < size) { *(buf + *pos) = dig[num]; } else { *(buf + (size - 1)) = '\0'; return(1); }// *pos += 1; } *(buf + *pos) = '\0'; return(1);} /* send ZFILE header and filename & info. Wait for response * from receiver. */static int ZmSendFilename( ZModem *info ){ int err; int pos; u_char obuf[1024]; info->state = FileWait ; err = ZXmitHdr(ZFILE, ZBIN, info->fileFlags, info); if(err) { return(err); } pos = 0; while(pos < 1024) { obuf[pos] = *(info->rfilename + pos); if(obuf[pos] == '\0') { pos++; break; } pos++; } if(pos >= 1024) { pos = 1023; obuf[pos] = '\0'; } ZmPutLong(obuf, & pos, 1024, info->len , 10); /* %d */ ZmPutStr (obuf, & pos, 1024, " "); ZmPutLong(obuf, & pos, 1024, info->date , 8); /* %lo */ ZmPutStr (obuf, & pos, 1024, " "); ZmPutLong(obuf, & pos, 1024, info->mode , 8); /* %o */ ZmPutStr (obuf, & pos, 1024, " "); ZmPutLong(obuf, & pos, 1024, 0 , 10); /* 0 */ ZmPutStr (obuf, & pos, 1024, " "); ZmPutLong(obuf, & pos, 1024, info->filesRem, 10); /* %d */ ZmPutStr (obuf, & pos, 1024, " "); ZmPutLong(obuf, & pos, 1024, info->bytesRem, 10); /* %d */ ZmPutStr (obuf, & pos, 1024, " "); ZmPutLong(obuf, & pos, 1024, 0 , 10); /* 0 */ ZmPutStr (obuf, & pos, 1024, " "); if(pos >= 1024) { obuf[1023] = '\0'; pos = 1023; } return(ZXmitData(ZBIN, pos + 1, ZCRCW, obuf, info));}/* called by user when there are no more files to send */int ZmTFinish( ZModem *info ){ if( info->Protocol == XMODEM ) return ZmDone ; if( info->Protocol == YMODEM ) { return YSendFin(info) ; } info->state = TFinish ; if( info->buffer != NULL ) { info->buffer = NULL ; }#ifdef ZMODEMLOG zmodemlog("ZmTFinish[%s]: send ZFIN\n", ZmSname(info)) ;#endif // ZMODEMLOG return ZXmitHdr(ZFIN, ZHEX, zeros, info) ;}// /* sent ZRQINIT, waiting for response */ StateTable TStartOps[] = { {ZRINIT,ZmGotRinit,1,1,TStart}, {ZCHALLENGE,ZmAnswerChallenge,1,0,TStart}, {ZABORT,ZmGotAbort,1,1,TFinish}, {ZFERR,ZmGotAbort,1,1,TFinish}, {ZNAK,ZmIgnore,0,0,TStart}, {ZCOMMAND,ZmGotCommand,0,0,CommandData}, {ZSTDERR,ZmGotStderr,0,0,StderrData}, {99,ZmZPF,0,0,TStart}, } ; /* sent ZSINIT, waiting for response */ StateTable TInitOps[] = { {ZACK,ZmRetDone,1,0,TInit}, {ZNAK,ZmSendZSInit,1,0,TInit}, {ZRINIT,ZmGotRinit,1,1,TInit}, /* redundant, but who cares */ {ZCHALLENGE,ZmAnswerChallenge,1,0,TInit}, {ZABORT,ZmGotAbort,1,1,TFinish},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -