Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, for more info) to build successfully.

Commit 0f7716c0 authored by Rob Swindell's avatar Rob Swindell 💬

Strip/ignore high (parity) bit in ZPAD, ZDLE, and hex headers

The previous committed fix/issue raised some additional concerns about this "parity" bit:

Something I didn't notice before from the ZMODEM spec:
"The hex header receiving routine ignores parity."

And looking at lrzsz's zm.c, I see it goes even further and ignores the "parity" bit on the ZPAD and ZDLE bytes proceeding the frame encoding byte as well as in the frame encoding byte itself (so ZHEX, 'B' 0x22 and 0xC2 should be treated as equivalent).

I find it strange that some ZMODEM implementations (e.g. chuck's zshhdr()) would send the terminating LF with the even-parity bit set, but not set the even-parity flag for any of the frame content bytes. And then, expect that the parity flag may be set on incoming hex headers. I suppose it makes sense for 7-E-1 connections, but then the transmitted terminating LF would have had its parity flag set automatically (would not need to be set manually in the code). Add to the mysteries of ZMODEM that will likely never be solved.
parent 12ac1fc4
Pipeline #1315 passed with stage
in 9 minutes and 37 seconds
......@@ -64,6 +64,8 @@
#define HDRLEN 5 /* size of a zmodem header */
#define STRIPPED_PARITY(c) ((c) & 0x7f)
static int lprintf(zmodem_t* zm, int level, const char *fmt, ...)
va_list argptr;
......@@ -652,7 +654,7 @@ int zmodem_send_zeof(zmodem_t* zm)
* check the data stream for 5 consecutive CAN characters;
* and if you see them abort. this saves a lot of clutter in
* the rest of the code; even though it is a very strange place
* for an exit. (but that was wat session abort was all about.)
* for an exit. (but that was what session abort was all about.)
int zmodem_recv_raw(zmodem_t* zm)
......@@ -816,7 +818,7 @@ int zmodem_rx(zmodem_t* zm)
* return 1 with correct packet frame continues
* return 0 with incorrect frame.
* return TIMEOUT with a timeout
* if an acknowledgement is requested it is generated automatically
* if an acknowledgment is requested it is generated automatically
* here.
......@@ -1018,6 +1020,7 @@ int zmodem_recv_nibble(zmodem_t* zm)
if(c < 0)
return c;
if(c > '9') {
if(c < 'a' || c > 'f') {
......@@ -1235,12 +1238,12 @@ int zmodem_recv_header_raw(zmodem_t* zm)
} while(c != ZPAD);
} while(STRIPPED_PARITY(c) != ZPAD);
if((c = zmodem_recv_raw(zm)) < 0)
if(c == ZPAD) {
if((c = zmodem_recv_raw(zm)) < 0)
......@@ -1249,7 +1252,7 @@ int zmodem_recv_header_raw(zmodem_t* zm)
* spurious ZPAD check
if(c != ZDLE) {
lprintf(zm,LOG_DEBUG, "%s Expected ZDLE, received: %s", __FUNCTION__, chr(c));
......@@ -1260,7 +1263,7 @@ int zmodem_recv_header_raw(zmodem_t* zm)
c = zmodem_rx(zm);
switch (c) {
switch (STRIPPED_PARITY(c)) {
case ZBIN:
return INVHDR;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment