Update first part of zmodem sources

This commit is contained in:
Michiel Broek 2004-11-07 13:35:34 +00:00
parent cb2d964597
commit 706d0fcfe7
3 changed files with 208 additions and 230 deletions

View File

@ -53,15 +53,16 @@
static void zputhex(int); static void zputhex(int);
static void zsbh32(int,char*,int,int); static void zsbh32(int,char*,int,int);
static void zsda32(char*,int,int); static void zsda32(char*,int,int);
static int zrdat32(char*,int); static int zrdat32(char*,int);
static int noxrd7(void); static int noxrd7(void);
static int zrbhd32(char*); static int zrbhd32(char*);
static int zrbhdr(char*); static int zrbhdr(char*);
static int zrhhdr(char*); static int zrhhdr(char*);
static int zgethex(void); static int zgethex(void);
static int zgeth1(void); static int zgeth1(void);
static void garbitch(void); static void garbitch(void);
#include "../config.h" #include "../config.h"
#include "../lib/mbselib.h" #include "../lib/mbselib.h"
#include "../lib/nodelist.h" #include "../lib/nodelist.h"
@ -163,16 +164,16 @@ static int frame_length = 0;
void get_frame_buffer(void) void get_frame_buffer(void)
{ {
if (frame_buffer == NULL) if (frame_buffer == NULL)
frame_buffer = malloc(FRAME_BUFFER_SIZE); frame_buffer = malloc(FRAME_BUFFER_SIZE);
} }
void free_frame_buffer(void) void free_frame_buffer(void)
{ {
if (frame_buffer) if (frame_buffer)
free(frame_buffer); free(frame_buffer);
frame_buffer = NULL; frame_buffer = NULL;
} }
@ -182,45 +183,43 @@ void free_frame_buffer(void)
*/ */
void zsbhdr(int len, int type, register char *shdr) void zsbhdr(int len, int type, register char *shdr)
{ {
register int n; register int n;
register unsigned short crc; register unsigned short crc;
Syslog('z', "zsbhdr: %c %d %s %lx", Usevhdrs?'v':'f', len, frametypes[type+FTOFFSET], rclhdr(shdr)); Syslog('z', "zsbhdr: %c %d %s %lx", Usevhdrs?'v':'f', len, frametypes[type+FTOFFSET], rclhdr(shdr));
BUFFER_CLEAR(); BUFFER_CLEAR();
if (type == ZDATA) if (type == ZDATA)
for (n = Znulls; --n >=0; ) for (n = Znulls; --n >=0; )
BUFFER_BYTE(0); BUFFER_BYTE(0);
BUFFER_BYTE(ZPAD); BUFFER_BYTE(ZDLE); BUFFER_BYTE(ZPAD); BUFFER_BYTE(ZDLE);
switch (Crc32t=Txfcs32) { switch (Crc32t=Txfcs32) {
case 2: case 2: zsbh32(len, shdr, type, Usevhdrs?ZVBINR32:ZBINR32);
zsbh32(len, shdr, type, Usevhdrs?ZVBINR32:ZBINR32); BUFFER_FLUSH();
BUFFER_FLUSH(); break; break;
case 1: case 1: zsbh32(len, shdr, type, Usevhdrs?ZVBIN32:ZBIN32);
zsbh32(len, shdr, type, Usevhdrs?ZVBIN32:ZBIN32); break; break;
default: default: if (Usevhdrs) {
if (Usevhdrs) {
BUFFER_BYTE(ZVBIN); BUFFER_BYTE(ZVBIN);
zsendline(len); zsendline(len);
} } else
else
BUFFER_BYTE(ZBIN); BUFFER_BYTE(ZBIN);
zsendline(type); zsendline(type);
crc = updcrc16(type, 0); crc = updcrc16(type, 0);
for (n=len; --n >= 0; ++shdr) { for (n=len; --n >= 0; ++shdr) {
zsendline(*shdr); zsendline(*shdr);
crc = updcrc16((0377& *shdr), crc); crc = updcrc16((0377& *shdr), crc);
} }
crc = updcrc16(0,updcrc16(0,crc)); crc = updcrc16(0,updcrc16(0,crc));
zsendline(((int)(crc>>8))); zsendline(((int)(crc>>8)));
zsendline(crc); zsendline(crc);
} }
BUFFER_FLUSH(); BUFFER_FLUSH();
} }
@ -230,24 +229,24 @@ void zsbhdr(int len, int type, register char *shdr)
*/ */
void zsbh32(int len, register char *shdr, int type, int flavour) void zsbh32(int len, register char *shdr, int type, int flavour)
{ {
register int n; register int n;
register unsigned long crc; register unsigned long crc;
BUFFER_BYTE(flavour); BUFFER_BYTE(flavour);
if (Usevhdrs) if (Usevhdrs)
zsendline(len); zsendline(len);
zsendline(type); zsendline(type);
crc = 0xFFFFFFFFL; crc = updcrc32(type, crc); crc = 0xFFFFFFFFL; crc = updcrc32(type, crc);
for (n=len; --n >= 0; ++shdr) { for (n=len; --n >= 0; ++shdr) {
crc = updcrc32((0377 & *shdr), crc); crc = updcrc32((0377 & *shdr), crc);
zsendline(*shdr); zsendline(*shdr);
} }
crc = ~crc; crc = ~crc;
for (n=4; --n >= 0;) { for (n=4; --n >= 0;) {
zsendline((int)crc); zsendline((int)crc);
crc >>= 8; crc >>= 8;
} }
} }
@ -257,45 +256,44 @@ void zsbh32(int len, register char *shdr, int type, int flavour)
*/ */
void zshhdr(int len, int type, register char *shdr) void zshhdr(int len, int type, register char *shdr)
{ {
register int n; register int n;
register unsigned short crc; register unsigned short crc;
Syslog('z', "zshhdr: %c %d %s %ld", Usevhdrs?'v':'f', len, frametypes[type+FTOFFSET], rclhdr(shdr)); Syslog('z', "zshhdr: %c %d %s %ld", Usevhdrs?'v':'f', len, frametypes[type+FTOFFSET], rclhdr(shdr));
BUFFER_CLEAR(); BUFFER_CLEAR();
BUFFER_BYTE(ZPAD); BUFFER_BYTE(ZPAD);
BUFFER_BYTE(ZPAD); BUFFER_BYTE(ZPAD);
BUFFER_BYTE(ZDLE); BUFFER_BYTE(ZDLE);
if (Usevhdrs) { if (Usevhdrs) {
BUFFER_BYTE(ZVHEX); BUFFER_BYTE(ZVHEX);
zputhex(len); zputhex(len);
} } else
else BUFFER_BYTE(ZHEX);
BUFFER_BYTE(ZHEX); zputhex(type);
zputhex(type); Crc32t = 0;
Crc32t = 0;
crc = updcrc16(type, 0); crc = updcrc16(type, 0);
for (n=len; --n >= 0; ++shdr) { for (n=len; --n >= 0; ++shdr) {
zputhex(*shdr); crc = updcrc16((0377 & *shdr), crc); zputhex(*shdr); crc = updcrc16((0377 & *shdr), crc);
} }
crc = updcrc16(0,updcrc16(0,crc)); crc = updcrc16(0,updcrc16(0,crc));
zputhex(((int)(crc>>8))); zputhex(crc); zputhex(((int)(crc>>8))); zputhex(crc);
/* /*
* Make it printable on remote machine * Make it printable on remote machine
*/ */
BUFFER_BYTE(015); BUFFER_BYTE(015);
BUFFER_BYTE(0212); BUFFER_BYTE(0212);
/* /*
* Uncork the remote in case a fake XOFF has stopped data flow * Uncork the remote in case a fake XOFF has stopped data flow
*/ */
if (type != ZFIN && type != ZACK) if (type != ZFIN && type != ZACK)
BUFFER_BYTE(021); BUFFER_BYTE(021);
BUFFER_FLUSH(); BUFFER_FLUSH();
} }
@ -306,58 +304,58 @@ void zshhdr(int len, int type, register char *shdr)
char *Zendnames[] = {(char *)"ZCRCE",(char *)"ZCRCG",(char *)"ZCRCQ",(char *)"ZCRCW"}; char *Zendnames[] = {(char *)"ZCRCE",(char *)"ZCRCG",(char *)"ZCRCQ",(char *)"ZCRCW"};
void zsdata(register char *buf, int length, int frameend) void zsdata(register char *buf, int length, int frameend)
{ {
register unsigned short crc; register unsigned short crc;
Syslog('z', "zsdata: %d %s", length, Zendnames[(frameend-ZCRCE)&3]); Syslog('z', "zsdata: %d %s", length, Zendnames[(frameend-ZCRCE)&3]);
BUFFER_CLEAR(); BUFFER_CLEAR();
switch (Crc32t) { switch (Crc32t) {
case 1: case 1: zsda32(buf, length, frameend);
zsda32(buf, length, frameend); break; break;
case 2: case 2: zsdar32(buf, length, frameend);
zsdar32(buf, length, frameend); break; break;
default: default: crc = 0;
crc = 0; for (;--length >= 0; ++buf) {
for (;--length >= 0; ++buf) {
zsendline(*buf); crc = updcrc16((0377 & *buf), crc); zsendline(*buf); crc = updcrc16((0377 & *buf), crc);
} }
BUFFER_BYTE(ZDLE); BUFFER_BYTE(frameend); BUFFER_BYTE(ZDLE);
crc = updcrc16(frameend, crc); BUFFER_BYTE(frameend);
crc = updcrc16(frameend, crc);
crc = updcrc16(0,updcrc16(0,crc)); crc = updcrc16(0,updcrc16(0,crc));
zsendline(((int)(crc>>8))); zsendline(crc); zsendline(((int)(crc>>8))); zsendline(crc);
} }
if (frameend == ZCRCW) if (frameend == ZCRCW)
BUFFER_BYTE(XON); BUFFER_BYTE(XON);
BUFFER_FLUSH(); BUFFER_FLUSH();
} }
void zsda32(register char *buf, int length, int frameend) void zsda32(register char *buf, int length, int frameend)
{ {
register int c; register int c;
register unsigned long crc; register unsigned long crc;
crc = 0xFFFFFFFFL; crc = 0xFFFFFFFFL;
for (;--length >= 0; ++buf) { for (;--length >= 0; ++buf) {
c = *buf & 0377; c = *buf & 0377;
if (c & 0140) if (c & 0140)
BUFFER_BYTE(lastsent = c); BUFFER_BYTE(lastsent = c);
else else
zsendline(c); zsendline(c);
crc = updcrc32(c, crc); crc = updcrc32(c, crc);
} }
BUFFER_BYTE(ZDLE); BUFFER_BYTE(ZDLE);
BUFFER_BYTE(frameend); BUFFER_BYTE(frameend);
crc = updcrc32(frameend, crc); crc = updcrc32(frameend, crc);
crc = ~crc; crc = ~crc;
for (c=4; --c >= 0;) { for (c=4; --c >= 0;) {
zsendline((int)crc); crc >>= 8; zsendline((int)crc); crc >>= 8;
} }
} }
@ -491,7 +489,7 @@ crcfoo:
void garbitch(void) void garbitch(void)
{ {
Syslog('+', "Zmodem: Garbled data subpacket"); Syslog('+', "Zmodem: Garbled data subpacket");
} }

View File

@ -6,23 +6,14 @@
void get_frame_buffer(void); void get_frame_buffer(void);
void free_frame_buffer(void); void free_frame_buffer(void);
void zsbhdr(int, int, register char *); void zsbhdr(int, int, register char *);
void zsbh32(int, register char *, int, int);
void zshhdr(int, int, register char *); void zshhdr(int, int, register char *);
void zsdata(register char *, int, int); void zsdata(register char *, int, int);
void zsda32(register char *, int, int);
int zrdata(register char *, int); int zrdata(register char *, int);
int zrdat32(register char *, int); int zrdat32(register char *, int);
void garbitch(void);
int zgethdr(char *); int zgethdr(char *);
int zrbhdr(register char *); int zrbhdr(register char *);
int zrbhd32(register char *);
int zrhhdr(char *);
void zputhex(register int);
void zsendline(int); void zsendline(int);
int zgethex(void);
int zgeth1(void);
int zdlread(void); int zdlread(void);
int noxrd7(void);
void stohdr(long); void stohdr(long);
long rclhdr(register char *); long rclhdr(register char *);

View File

@ -51,58 +51,54 @@
*/ */
void zsdar32(char *buf, int length, int frameend) void zsdar32(char *buf, int length, int frameend)
{ {
register int c, l, n; register int c, l, n;
register unsigned long crc; register unsigned long crc;
crc = 0xFFFFFFFFL; l = *buf++ & 0377; crc = 0xFFFFFFFFL; l = *buf++ & 0377;
if (length == 1) { if (length == 1) {
zsendline(l); crc = updcrc32(l, crc); zsendline(l); crc = updcrc32(l, crc);
if (l == ZRESC) { if (l == ZRESC) {
zsendline(1); crc = updcrc32(1, crc); zsendline(1); crc = updcrc32(1, crc);
} }
} else { } else {
for (n = 0; --length >= 0; ++buf) { for (n = 0; --length >= 0; ++buf) {
if ((c = *buf & 0377) == l && n < 126 && length>0) { if ((c = *buf & 0377) == l && n < 126 && length>0) {
++n; continue; ++n; continue;
} }
switch (n) { switch (n) {
case 0: case 0: zsendline(l);
zsendline(l); crc = updcrc32(l, crc);
if (l == ZRESC) {
zsendline(0100); crc = updcrc32(0100, crc);
}
l = c; break;
case 1: if (l != ZRESC) {
zsendline(l); zsendline(l);
crc = updcrc32(l, crc);
crc = updcrc32(l, crc); crc = updcrc32(l, crc);
if (l == ZRESC) {
zsendline(0100); crc = updcrc32(0100, crc);
}
l = c; break;
case 1:
if (l != ZRESC) {
zsendline(l); zsendline(l);
crc = updcrc32(l, crc);
crc = updcrc32(l, crc);
n = 0; l = c; break;
}
/* **** FALL THRU TO **** */
default:
zsendline(ZRESC); crc = updcrc32(ZRESC, crc);
if (l == 040 && n < 34) {
n += 036;
zsendline(n); crc = updcrc32(n, crc);
}
else {
n += 0101;
zsendline(n); crc = updcrc32(n, crc);
zsendline(l); crc = updcrc32(l, crc);
}
n = 0; l = c; break; n = 0; l = c; break;
} }
} /* **** FALL THRU TO **** */
default: zsendline(ZRESC); crc = updcrc32(ZRESC, crc);
if (l == 040 && n < 34) {
n += 036;
zsendline(n); crc = updcrc32(n, crc);
} else {
n += 0101;
zsendline(n); crc = updcrc32(n, crc);
zsendline(l); crc = updcrc32(l, crc);
}
n = 0; l = c; break;
}
} }
PUTCHAR(ZDLE); PUTCHAR(frameend); }
crc = updcrc32(frameend, crc); PUTCHAR(ZDLE); PUTCHAR(frameend);
crc = updcrc32(frameend, crc);
crc = ~crc; crc = ~crc;
for (length=4; --length >= 0;) { for (length=4; --length >= 0;) {
zsendline((int)crc); crc >>= 8; zsendline((int)crc); crc >>= 8;
} }
} }
@ -111,86 +107,79 @@ void zsdar32(char *buf, int length, int frameend)
*/ */
int zrdatr32(register char *buf, int length) int zrdatr32(register char *buf, int length)
{ {
register int c; register int c;
register unsigned long crc; register unsigned long crc;
register char *end; register char *end;
register int d; register int d;
crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length; crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length;
d = 0; /* Use for RLE decoder state */ d = 0; /* Use for RLE decoder state */
while (buf <= end) { while (buf <= end) {
if ((c = zdlread()) & ~0377) { if ((c = zdlread()) & ~0377) {
crcfoo: crcfoo:
switch (c) { switch (c) {
case GOTCRCE: case GOTCRCE:
case GOTCRCG: case GOTCRCG:
case GOTCRCQ: case GOTCRCQ:
case GOTCRCW: case GOTCRCW: d = c; c &= 0377;
d = c; c &= 0377;
crc = updcrc32(c, crc); crc = updcrc32(c, crc);
if ((c = zdlread()) & ~0377) if ((c = zdlread()) & ~0377)
goto crcfoo; goto crcfoo;
crc = updcrc32(c, crc); crc = updcrc32(c, crc);
if ((c = zdlread()) & ~0377) if ((c = zdlread()) & ~0377)
goto crcfoo; goto crcfoo;
crc = updcrc32(c, crc); crc = updcrc32(c, crc);
if ((c = zdlread()) & ~0377) if ((c = zdlread()) & ~0377)
goto crcfoo; goto crcfoo;
crc = updcrc32(c, crc); crc = updcrc32(c, crc);
if ((c = zdlread()) & ~0377) if ((c = zdlread()) & ~0377)
goto crcfoo; goto crcfoo;
crc = updcrc32(c, crc); crc = updcrc32(c, crc);
if (crc != 0xDEBB20E3) { if (crc != 0xDEBB20E3) {
Syslog('+', "Zmodem zrdatr32: Bad CRC"); Syslog('+', "Zmodem zrdatr32: Bad CRC");
return TERROR; return TERROR;
} }
Rxcount = length - (end - buf); Rxcount = length - (end - buf);
Syslog('z', "zrdatr32: %d %s", Rxcount, Syslog('z', "zrdatr32: %d %s", Rxcount, Zendnames[(d-GOTCRCE)&3]);
Zendnames[(d-GOTCRCE)&3]);
return d; return d;
case GOTCAN: case GOTCAN: Syslog('+', "Zmodem: Sender Canceled");
Syslog('+', "Zmodem: Sender Canceled");
return ZCAN; return ZCAN;
case TIMEOUT: case TIMEOUT: Syslog('+', "Zmodem: TIMEOUT");
Syslog('+', "Zmodem: TIMEOUT");
return c; return c;
default: default: Syslog('+', "Zmodem: Bad data subpacket");
Syslog('+', "Zmodem: Bad data subpacket");
return c; return c;
} }
} }
crc = updcrc32(c, crc); crc = updcrc32(c, crc);
switch (d) { switch (d) {
case 0: case 0: if (c == ZRESC) {
if (c == ZRESC) { d = -1; continue;
d = -1; continue;
} }
*buf++ = c; continue; *buf++ = c; continue;
case -1: case -1: if (c >= 040 && c < 0100) {
if (c >= 040 && c < 0100) { d = c - 035; c = 040; goto spaces;
d = c - 035; c = 040; goto spaces;
} }
if (c == 0100) { if (c == 0100) {
d = 0; d = 0;
*buf++ = ZRESC; continue; *buf++ = ZRESC; continue;
} }
d = c; continue; d = c; continue;
default: default: d -= 0100;
d -= 0100;
if (d < 1) if (d < 1)
goto badpkt; goto badpkt;
spaces: spaces:
if ((buf + d) > end) if ((buf + d) > end)
goto badpkt; goto badpkt;
while ( --d >= 0) while ( --d >= 0)
*buf++ = c; *buf++ = c;
d = 0; continue; d = 0; continue;
}
} }
}
badpkt: badpkt:
Syslog('+', "Zmodem: Data subpacket too long"); Syslog('+', "Zmodem: Data subpacket too long");
return TERROR; return TERROR;
} }