AmendHub

Download:

jcs

/

subtext

/

amendments

/

186

zmodem: Improve debug logging, do 32-bit CRC, disable overlapping I/O

Since our output and input functions will bypass the telnet code that
escapes or unescapes IACs, add an option to do it here before
interfacing with the send/recv routines.
 
Interoperability testing with SyncTERM showed that it was too eager
to timeout when we didn't respond fast enough in acceping uploaded
data and writing it, so disable overlapping I/O. This way it won't
send more data to us until we've acked it.

jcs made amendment 186 about 1 year ago
--- zmodem.c Mon Jul 4 23:44:50 2022 +++ zmodem.c Mon Jul 11 10:33:26 2022 @@ -30,22 +30,17 @@ */ #include <stdarg.h> -#if THINK_C -#include "util.h" -#else -#include <stdbool.h> -#endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> -#if THINK_C -#include <unix.h> -#endif -#include "zmodem.h" #include "crc.h" +#include "util.h" +#include "zmodem.h" +/* #define ZMODEM_DEBUG */ + #ifdef ZMODEM_DEBUG #include "logger.h" extern struct logger *logger; @@ -140,6 +135,7 @@ extern struct logger *logger; #define ZCNL 2 #define XON 0x11 +#define IAC 0xff short ZRead1Byte(struct zmodem_session *, unsigned char *); void ZPutHex(struct zmodem_session *, short *, unsigned char); @@ -168,17 +164,13 @@ bool ZCheckHdr(struct zmodem_session *); void ZParseRInit(struct zmodem_session *); bool ZParseSInit(struct zmodem_session *); void ZParseHdr(struct zmodem_session *); -bool FTCreateFile(struct zmodem_session *); +bool ZCreateTemporaryFile(struct zmodem_session *); bool ZParseFile(struct zmodem_session *); bool ZWriteData(struct zmodem_session *); void ZCheckData(struct zmodem_session *); #ifdef ZMODEM_DEBUG -#define LOGBUFSIZE 256 -static char recvbuf[LOGBUFSIZE]; -static char sendbuf[LOGBUFSIZE]; - static const char * hdrtype_name(short type) { @@ -207,8 +199,8 @@ hdrtype_name(short type) if (type >= ZRQINIT && type <= ZSTDERR) return (s[type]); - else - return NULL; + + return NULL; } static const char * @@ -237,40 +229,10 @@ state_name(struct zmodem_session *zs) if (zs->ZState >= Z_RecvInit && zs->ZState <= Z_End) return (s[zs->ZState]); - else - return NULL; + + return NULL; } -static void -add_recvbuf(struct zmodem_session *zs, char *fmt, ...) -{ - va_list arg; - char buf[128]; - - va_start(arg, fmt); - vsnprintf(buf, sizeof(buf), fmt, arg); - strlcat(recvbuf, buf, sizeof(recvbuf)); - va_end(arg); - - logger_printf(logger, "recvbuf: %s (state %s)", recvbuf, state_name(zs)); - recvbuf[0] = '\0'; -} - -static void -add_sendbuf(struct zmodem_session *zs, char *fmt, ...) -{ - va_list arg; - char buf[128]; - - va_start(arg, fmt); - vsnprintf(buf, sizeof(buf), fmt, arg); - strlcat(sendbuf, buf, sizeof(sendbuf)); - va_end(arg); - - logger_printf(logger, "recvbuf: %s (state %s)", recvbuf, state_name(zs)); - sendbuf[0] = '\0'; -} - #endif /* ZMODEM_DEBUG */ struct zmodem_session * @@ -316,13 +278,39 @@ ZCreateReceiver(void) short ZRead1Byte(struct zmodem_session *zs, unsigned char *b) { + if (zs->DoIACEscape && zs->LastIAC != 0 && zs->LastIAC != IAC) { + *b = zs->LastIAC; + zs->LastIAC = 0; + return 1; + } + if (zs->recv(zs->cookie, b) == 0) return 0; + if (zs->DoIACEscape && zs->LastIAC) { + if (*b == IAC) { + zs->LastIAC = 0; + return 1; + } + + /* + * The IAC was not escaping an IAC, so return IAC this time and + * save the byte we just read for the next iteration. + */ + zs->LastIAC = *b; + *b = IAC; + return 1; + } + + if (zs->DoIACEscape && *b == IAC) { + zs->LastIAC = IAC; + return 0; + } + /* ignore 0x11, 0x13, 0x81 and 0x83 */ if (((*b & 0x7F) == 0x11) || ((*b & 0x7F) == 0x13)) return 0; - + return 1; } @@ -377,9 +365,9 @@ ZShHdr(struct zmodem_session *zs, unsigned char HdrTyp } ZPutHex(zs, &(zs->PktOutCount), HIBYTE(zs->CRC)); ZPutHex(zs, &(zs->PktOutCount), LOBYTE(zs->CRC)); - zs->PktOut[zs->PktOutCount] = '\r'; //0x8D; + zs->PktOut[zs->PktOutCount] = 0x8D; zs->PktOutCount++; - zs->PktOut[zs->PktOutCount] = '\n'; //0x8A; + zs->PktOut[zs->PktOutCount] = 0x8A; zs->PktOutCount++; if ((HdrType != ZFIN) && (HdrType != ZACK)) { @@ -391,13 +379,8 @@ ZShHdr(struct zmodem_session *zs, unsigned char HdrTyp zs->Sending = true; #ifdef ZMODEM_DEBUG - add_sendbuf(zs, "ZShHdr: %s", hdrtype_name(HdrType)); - - if (HdrType == ZRPOS) { - long pos; - memcpy(&pos, (unsigned long *)&zs->TxHdr[ZP0], 4); - add_sendbuf(zs, " offset=%ld", pos); - } + logger_printf(logger, "[%s] ZShHdr: %s", state_name(zs), + hdrtype_name(HdrType)); #endif } @@ -473,7 +456,8 @@ ZSbHdr(struct zmodem_session *zs, unsigned char HdrTyp zs->Sending = true; #ifdef ZMODEM_DEBUG - add_sendbuf(zs, "ZSbHdr: %s ", hdrtype_name(HdrType)); + logger_printf(logger, "[%s] ZSbHdr: %s", state_name(zs), + hdrtype_name(HdrType)); #endif } @@ -489,12 +473,12 @@ ZStoHdr(struct zmodem_session *zs, unsigned long Pos) long ZRclHdr(struct zmodem_session *zs) { - unsigned long L; + unsigned long l; - L = (unsigned char)(zs->RxHdr[ZP3]); - L = (L << 8) + (unsigned char)(zs->RxHdr[ZP2]); - L = (L << 8) + (unsigned char)(zs->RxHdr[ZP1]); - return ((L << 8) + (unsigned char)(zs->RxHdr[ZP0])); + l = (unsigned char)(zs->RxHdr[ZP3]); + l = (l << 8) + (unsigned char)(zs->RxHdr[ZP2]); + l = (l << 8) + (unsigned char)(zs->RxHdr[ZP1]); + return ((l << 8) + (unsigned char)(zs->RxHdr[ZP0])); } void @@ -502,7 +486,7 @@ ZSendRInit(struct zmodem_session *zs) { zs->Pos = 0; ZStoHdr(zs, 0); - zs->TxHdr[ZF0] = /* CANFC32 | */ CANFDX | CANOVIO; + zs->TxHdr[ZF0] = CANFC32 | CANFDX; // | CANOVIO; if (zs->CtlEsc) zs->TxHdr[ZF0] = zs->TxHdr[ZF0] | ESCCTL; ZShHdr(zs, ZRINIT); @@ -575,18 +559,18 @@ ZSendCancel(struct zmodem_session *zs) zs->ZState = Z_Cancel; #ifdef ZMODEM_DEBUG - add_sendbuf(zs, "ZSendCancel"); + logger_printf(logger, "[%s] ZSendCancel", state_name(zs)); #endif } void ZSendInitHdr(struct zmodem_session *zs) { + zs->ZState = Z_SendInitHdr; ZStoHdr(zs, 0); if (zs->CtlEsc) zs->TxHdr[ZF0] = ESCCTL; ZShHdr(zs, ZSINIT); - zs->ZState = Z_SendInitHdr; } void @@ -611,29 +595,37 @@ ZSendInitDat(struct zmodem_session *zs) zs->ZState = Z_SendInitDat; #ifdef ZMODEM_DEBUG - add_sendbuf(zs, "ZSendInitDat"); + logger_printf(logger, "[%s] ZSendInitDat", state_name(zs)); #endif } void ZSendFileHdr(struct zmodem_session *zs) { + zs->ZState = Z_SendFileHdr; ZStoHdr(zs, 0); if (zs->BinFlag) zs->TxHdr[ZF0] = ZCBIN; /* binary file */ else zs->TxHdr[ZF0] = ZCNL; /* text file, convert newline */ ZSbHdr(zs, ZFILE); - zs->ZState = Z_SendFileHdr; + +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZSendFileHdr: %s", state_name(zs), + zs->BinFlag ? "binary" : "text"); +#endif } void ZSendFileDat(struct zmodem_session *zs) { short i, j; - struct stat sb; if (!zs->file) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZSendFileDat: no file, canceling", + state_name(zs)); +#endif ZSendCancel(zs); return; } @@ -656,17 +648,9 @@ ZSendFileDat(struct zmodem_session *zs) * files remaining (dec) * bytes remaining (dec) */ -#if THINK_C snprintf((char *)zs->PktOut + zs->PktOutCount, sizeof(zs->PktOut) - zs->PktOutCount, "%lu 0 100644 0 0", zs->file_size); -#else - fstat(fileno(zs->file), &sb); - snprintf(&(zs->PktOut[zs->PktOutCount]), - sizeof(zs->PktOut) - zs->PktOutCount, - "%lu %lo %o", zs->file_size, (unsigned long)sb.st_mtim.tv_sec, - sb.st_mode); -#endif j = strlen((char *)zs->PktOut + zs->PktOutCount); for (i = 0; i <= j; i++) { zs->CRC = UpdateCRC(zs->PktOut[zs->PktOutCount], zs->CRC); @@ -687,22 +671,22 @@ ZSendFileDat(struct zmodem_session *zs) zs->PktOutPtr = 0; zs->Sending = true; zs->ZState = Z_SendFileDat; - + fseek(zs->file, 0, SEEK_SET); #ifdef ZMODEM_DEBUG - add_sendbuf(zs, "ZSendFileDat: ZFILE: ZF0=%x ZF1=%x ZF2=%x file=%s size=%lu", - zs->TxHdr[ZF0], zs->TxHdr[ZF1],zs->TxHdr[ZF2], - zs->file_name, zs->file_size); + logger_printf(logger, "[%s] ZSendFileDat: ZFILE: ZF0=%x ZF1=%x " + "ZF2=%x file=%s size=%lu", state_name(zs), zs->TxHdr[ZF0], + zs->TxHdr[ZF1],zs->TxHdr[ZF2], zs->file_name, zs->file_size); #endif } void ZSendDataHdr(struct zmodem_session *zs) { + zs->ZState = Z_SendDataHdr; ZStoHdr(zs, zs->Pos); ZSbHdr(zs, ZDATA); - zs->ZState = Z_SendDataHdr; } void @@ -712,6 +696,10 @@ ZSendDataDat(struct zmodem_session *zs) unsigned char b; if (zs->Pos >= zs->file_size) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZSendDataDat: pos %lu >= file size " + "%lu, EOFing", state_name(zs), zs->Pos, zs->file_size); +#endif zs->Pos = zs->file_size; ZSendEOF(zs); fclose(zs->file); @@ -757,15 +745,16 @@ ZSendDataDat(struct zmodem_session *zs) zs->ZState = Z_SendDataDat; #ifdef ZMODEM_DEBUG - /* add_sendbuf("ZSendDataDat pos=%ld", zs->Pos); */ + logger_printf(logger, "[%s] ZSendDataDat: pos=%ld", state_name(zs), + zs->Pos); #endif } bool ZInit(struct zmodem_session *zs) { - zs->CtlEsc = 0; - zs->MaxDataLen = 1024; + zs->CtlEsc = false; + zs->MaxDataLen = ZMODEM_BLOCK_SIZE; zs->WinSize = 32767; if (zs->ZMode == IdZAutoR || zs->ZMode == IdZAutoS) { @@ -791,15 +780,20 @@ ZInit(struct zmodem_session *zs) zs->CanCount = 5; if (zs->MaxDataLen <= 0) - zs->MaxDataLen = 1024; + zs->MaxDataLen = ZMODEM_BLOCK_SIZE; if (zs->MaxDataLen < 64) zs->MaxDataLen = 64; - if (zs->MaxDataLen > 1024) - zs->MaxDataLen = 1024; + if (zs->MaxDataLen > ZMODEM_BLOCK_SIZE) + zs->MaxDataLen = ZMODEM_BLOCK_SIZE; - zs->TimeOut = 10; + zs->TimeOut = 30; ZResetTimeout(zs, zs->TimeOut); +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZInit: %s", state_name(zs), + zs->ZMode == IdZReceive ? "receive" : "send"); +#endif + switch (zs->ZMode) { case IdZReceive: zs->ZState = Z_RecvInit; @@ -807,9 +801,6 @@ ZInit(struct zmodem_session *zs) break; case IdZSend: zs->ZState = Z_SendInit; -#if 0 - zs->output("rz\r", 3); -#endif ZSendRQInit(zs); break; } @@ -820,6 +811,10 @@ ZInit(struct zmodem_session *zs) void ZTimeOutProc(struct zmodem_session *zs) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZTimeOutProc", state_name(zs)); +#endif + switch (zs->ZState) { case Z_RecvInit: ZSendRInit(zs); @@ -854,7 +849,20 @@ ZCheckHdr(struct zmodem_session *zs) ok = (zs->CRC == 0); } - if (!ok) { + if (ok) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZCheckHdr: CRC%s ok", state_name(zs), + zs->CRC32 ? "32" : "16"); +#endif + } else { +#ifdef ZMODEM_DEBUG + if (zs->CRC32) + logger_printf(logger, "[%s] ZCheckHdr: CRC32 check failed " + "(0x%lx != 0xDEBB20E3)", state_name(zs), zs->CRC3); + else + logger_printf(logger, "[%s] ZCheckHdr: CRC16 check failed " + "(0x%x != 0x0)", state_name(zs), zs->CRC); +#endif switch (zs->ZState) { case Z_RecvInit: ZSendRInit(zs); @@ -876,10 +884,19 @@ ZParseRInit(struct zmodem_session *zs) { short max; - if ((zs->ZState != Z_SendInit) && (zs->ZState != Z_SendEOF)) + if ((zs->ZState != Z_SendInit) && (zs->ZState != Z_SendEOF)) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZParseRInit: not in Init or EOF", + state_name(zs)); +#endif return; + } if (!zs->file) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZParseRInit: no file, FINing", + state_name(zs)); +#endif zs->ZState = Z_SendFIN; ZSendFIN(zs); return; @@ -896,10 +913,15 @@ ZParseRInit(struct zmodem_session *zs) max = (zs->RxHdr[ZP1] << 8) + zs->RxHdr[ZP0]; if (max <= 0) - max = 1024; + max = ZMODEM_BLOCK_SIZE; if (zs->MaxDataLen > max) zs->MaxDataLen = max; +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZParseRInit: max data len %d", + state_name(zs), zs->MaxDataLen); +#endif + zs->ZState = Z_SendFileHdr; ZSendFileHdr(zs); } @@ -907,8 +929,13 @@ ZParseRInit(struct zmodem_session *zs) bool ZParseSInit(struct zmodem_session *zs) { - if (zs->ZState != Z_RecvInit) + if (zs->ZState != Z_RecvInit) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZParseSInit: state not RecvInit", + state_name(zs)); +#endif return false; + } zs->ZState = Z_RecvInit2; zs->CtlEsc = zs->CtlEsc || ((zs->RxHdr[ZF0] & ESCCTL) != 0); @@ -920,7 +947,8 @@ void ZParseHdr(struct zmodem_session *zs) { #ifdef ZMODEM_DEBUG - add_recvbuf(zs, "ZParseHdr: RxType %s ", hdrtype_name(zs->RxType)); + logger_printf(logger, "[%s] ZParseHdr: RxType %s", state_name(zs), + hdrtype_name(zs->RxType)); #endif switch (zs->RxType) { @@ -997,7 +1025,12 @@ ZParseHdr(struct zmodem_session *zs) break; case ZFIN: if (zs->ZMode == IdZReceive) { +#if 0 zs->ZState = Z_RecvFIN; +#else + /* we only want to receive one file per session, just end */ + zs->ZState = Z_End; +#endif ZSendFIN(zs); zs->CanCount = 2; ZResetTimeout(zs, zs->TimeOut); @@ -1016,7 +1049,8 @@ ZParseHdr(struct zmodem_session *zs) zs->Pos = ZRclHdr(zs); zs->LastPos = zs->Pos; #ifdef ZMODEM_DEBUG - add_recvbuf(zs, " pos=%ld", zs->Pos); + logger_printf(logger, "[%s] ZParseHdr: pos=%ld", state_name(zs), + zs->Pos); #endif ZSendDataHdr(zs); break; @@ -1040,7 +1074,7 @@ ZParseHdr(struct zmodem_session *zs) if (zs->file) { if (zs->CRRecv) { zs->CRRecv = false; - fwrite("\012", 1, 1, zs->file); + fwrite("\r", 1, 1, zs->file); } fclose(zs->file); zs->file = NULL; @@ -1057,19 +1091,29 @@ ZParseHdr(struct zmodem_session *zs) } bool -FTCreateFile(struct zmodem_session *zs) +ZCreateTemporaryFile(struct zmodem_session *zs) { - /* check for existing file, bail if it exists */ - zs->file = fopen(zs->file_name, "r"); - if (zs->file != NULL) { - fclose(zs->file); - zs->file = NULL; + if (zs->upload_file_path[0] == '\0') { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZCreateTemporaryFile: no file path", + state_name(zs)); +#endif return false; } - - zs->file = fopen(zs->file_name, "wb+"); - if (zs->file == NULL) + + zs->file = fopen(zs->upload_file_path, "wb+"); + if (zs->file == NULL) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZCreateTemporaryFile: opening %s failed", + state_name(zs), zs->upload_file_path); +#endif return false; + } + +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZCreateTemporaryFile: %s", + state_name(zs), zs->upload_file_path); +#endif return true; } @@ -1084,11 +1128,14 @@ ZParseFile(struct zmodem_session *zs) short mode; short ret; - if ((zs->ZState != Z_RecvInit) && (zs->ZState != Z_RecvInit2)) + if ((zs->ZState != Z_RecvInit) && (zs->ZState != Z_RecvInit2)) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZParseFile: state not RecvInit/2", + state_name(zs)); +#endif return false; - - /* kill timer */ - zs->TimeOutAt = 0; + } + zs->CRRecv = false; /* file name */ @@ -1097,28 +1144,26 @@ ZParseFile(struct zmodem_session *zs) /* don't allow paths in file name */ tfile_name = (char *)&zs->PktIn; i = 0; - do { - if (tfile_name[i] == '\0') - break; + while (tfile_name[i] != '\0') { if (tfile_name[i] == '/') { tfile_name += i + 1; i = 0; } i++; - } while (1); + } - zs->file_name = xstrdup(tfile_name); - if (zs->file_name == NULL) +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZParseFile: path \"%s\" -> \"%s\"", + state_name(zs), (char *)&zs->PktIn, tfile_name); +#endif + + if (tfile_name[0] == '\0') return false; - if (zs->file_name[0] == '\0') { - free(zs->file_name); - return false; - } + + strlcpy(zs->file_name, tfile_name, sizeof(zs->file_name)); - /* file open */ - if (!FTCreateFile(zs)) { - free(zs->file_name); - zs->file_name = NULL; + if (!ZCreateTemporaryFile(zs)) { + zs->file_name[0] = '\0'; return false; } @@ -1145,8 +1190,8 @@ ZParseFile(struct zmodem_session *zs) zs->Pos = 0; fseek(zs->file, 0, SEEK_SET); - ZStoHdr(zs, 0); zs->ZState = Z_RecvData; + ZStoHdr(zs, 0); /* set timeout for data */ ZResetTimeout(zs, zs->TimeOut); @@ -1160,10 +1205,14 @@ ZWriteData(struct zmodem_session *zs) short i; unsigned char b; - if (zs->ZState != Z_RecvData) + if (zs->ZState != Z_RecvData) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZWriteData: state != RecvData", + state_name(zs)); +#endif return false; - - /* kill timer */ + } + zs->TimeOutAt = 0; if (zs->BinFlag) @@ -1178,6 +1227,11 @@ ZWriteData(struct zmodem_session *zs) zs->CRRecv = b == 0x0D; fwrite(&b, 1, 1, zs->file); } + +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZWriteData: wrote %d byte(s) at %ld", + state_name(zs), zs->PktInPtr, zs->Pos); +#endif zs->Pos += zs->PktInPtr; fseek(zs->file, zs->Pos, SEEK_SET); @@ -1197,6 +1251,10 @@ ZCheckData(struct zmodem_session *zs) /* check CRC */ if ((zs->CRC32 && zs->CRC3 != 0xDEBB20E3) || (!zs->CRC32 && zs->CRC != 0)) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZCheckData: CRC%s failed", + state_name(zs), zs->CRC32 ? "32" : "16"); +#endif switch (zs->ZState) { case Z_RecvInit: case Z_RecvInit2: @@ -1209,6 +1267,7 @@ ZCheckData(struct zmodem_session *zs) zs->ZPktState = Z_PktGetPAD; return; } + /* parse data */ switch (zs->RxType) { case ZSINIT: @@ -1225,6 +1284,10 @@ ZCheckData(struct zmodem_session *zs) } if (!ok) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZCheckData: bad RxType %s, skipping", + state_name(zs), hdrtype_name(zs->RxType)); +#endif zs->ZPktState = Z_PktGetPAD; zs->ZState = Z_SendSkip; ZSendSkip(zs); @@ -1256,6 +1319,11 @@ ZCheckData(struct zmodem_session *zs) zs->ZPktState = Z_PktGetPAD; } +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZCheckData: TERM %s", state_name(zs), + hdrtype_name(zs->TERM)); +#endif + if (zs->ZPktState == Z_PktGetData) { zs->Quoted = false; zs->CRC = 0; @@ -1372,6 +1440,7 @@ ZParse(struct zmodem_session *zs) } zs->Quoted = false; } + zs->PktIn[zs->PktInPtr] = b; zs->PktInPtr++; zs->PktInCount--; @@ -1445,12 +1514,14 @@ ZParse(struct zmodem_session *zs) } zs->Quoted = false; } + if (zs->CRC32) zs->CRC3 = UpdateCRC32(b, zs->CRC3); else zs->CRC = UpdateCRC(b, zs->CRC); + if (zs->ZPktState == Z_PktGetData) { - if (zs->PktInPtr < 1024) { + if (zs->PktInPtr < ZMODEM_BLOCK_SIZE) { zs->PktIn[zs->PktInPtr] = b; zs->PktInPtr++; } else @@ -1520,12 +1591,20 @@ ZParse(struct zmodem_session *zs) void ZCancel(struct zmodem_session *zs) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZCancel", state_name(zs)); +#endif + ZSendCancel(zs); } void ZDestroy(struct zmodem_session *zs) { +#ifdef ZMODEM_DEBUG + logger_printf(logger, "[%s] ZDestroy", state_name(zs)); +#endif + if (zs->file) fclose(zs->file); if (zs->file_name) --- zmodem.h Mon Jul 4 20:46:10 2022 +++ zmodem.h Mon Jul 11 10:33:11 2022 @@ -30,16 +30,15 @@ #ifndef __ZMODEM_H__ #define __ZMODEM_H__ -//#include <stdbool.h> #include "util.h" -/* #define ZMODEM_DEBUG */ +#define ZMODEM_BLOCK_SIZE 1024 /* ZMODEM function id */ -#define IdZReceive 1 -#define IdZSend 2 -#define IdZAutoR 3 -#define IdZAutoS 4 +#define IdZReceive 1 +#define IdZSend 2 +#define IdZAutoR 3 +#define IdZAutoS 4 enum { ZMODEM_MODE, @@ -53,7 +52,8 @@ struct zmodem_session { FILE *file; unsigned long file_size; - char *file_name; + char file_name[256]; + char upload_file_path[256]; unsigned long file_mtime; unsigned char RxHdr[4], TxHdr[4]; @@ -66,10 +66,10 @@ struct zmodem_session { bool Sending; short ZMode, ZState, ZPktState; short MaxDataLen, TimeOut, CanCount; - bool CtlEsc, CRC32, HexLo, Quoted, CRRecv; + bool CtlEsc, CRC32, HexLo, Quoted, CRRecv, DoIACEscape; short CRC; long CRC3, Pos, LastPos, WinSize; - unsigned char LastSent; + unsigned char LastSent, LastIAC; unsigned long TimeOutAt; };