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 over 2 years 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;
};