Zmodem protocol changes
This commit is contained in:
parent
de58423731
commit
9d82aca2c3
@ -52,7 +52,7 @@ struct tchars oldtch, tch;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int hanged_up = 0;
|
int hanged_up = 0;
|
||||||
unsigned Baudrate = 2400;
|
unsigned Baudrate = 9600; /* Default, set by first io_mode() call */
|
||||||
int current_mode = -1;
|
int current_mode = -1;
|
||||||
|
|
||||||
|
|
||||||
@ -188,26 +188,29 @@ int io_mode(int fd, int n)
|
|||||||
#ifdef USE_TERMIOS
|
#ifdef USE_TERMIOS
|
||||||
case 2:
|
case 2:
|
||||||
if (!did0) {
|
if (!did0) {
|
||||||
did0 = TRUE;
|
|
||||||
tcgetattr(fd,&oldtty);
|
tcgetattr(fd,&oldtty);
|
||||||
}
|
}
|
||||||
tty = oldtty;
|
tty = oldtty;
|
||||||
|
|
||||||
tty.c_iflag = 0; /* Transparant input */
|
tty.c_iflag = BRKINT | IXON;
|
||||||
tty.c_oflag = 0; /* Transparent output */
|
tty.c_oflag = 0; /* Transparent output */
|
||||||
tty.c_cflag &= ~( CSIZE | CSTOPB | PARENB | PARODD); /* Disable parity and all character sizes */
|
tty.c_cflag &= ~( CSIZE | PARENB ); /* Disable parity and all character sizes */
|
||||||
tty.c_cflag |= CS8 | CREAD | HUPCL | CLOCAL;
|
tty.c_cflag |= CS8 | CREAD;
|
||||||
tty.c_lflag = 0;
|
tty.c_lflag = (protocol == ZM_ZMODEM) ? 0 : ISIG;
|
||||||
tty.c_cc[VMIN] = 1;
|
tty.c_cc[VINTR] = (protocol == ZM_ZMODEM) ? -1:030; /* Interrupt char */
|
||||||
tty.c_cc[VTIME] = 0;
|
tty.c_cc[VQUIT] = -1; /* Quit char */
|
||||||
|
tty.c_cc[VMIN] = 3; /* This many chars satisfies reads */
|
||||||
|
tty.c_cc[VTIME] = 1;
|
||||||
|
|
||||||
tcsetattr(fd,TCSADRAIN,&tty);
|
tcsetattr(fd,TCSADRAIN,&tty);
|
||||||
|
did0 = TRUE;
|
||||||
|
Baudrate = getspeed(cfgetospeed(&tty));
|
||||||
|
Syslog('t', "Baudrate = %d", Baudrate);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case 1:
|
case 1:
|
||||||
case 3:
|
case 3:
|
||||||
if (!did0) {
|
if (!did0) {
|
||||||
did0 = TRUE;
|
|
||||||
tcgetattr(fd,&oldtty);
|
tcgetattr(fd,&oldtty);
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
Syslog('t', "iflag%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
Syslog('t', "iflag%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||||
@ -313,37 +316,37 @@ int io_mode(int fd, int n)
|
|||||||
(oldtty.c_lflag & NOFLSH) ? " NOFLSH":"");
|
(oldtty.c_lflag & NOFLSH) ? " NOFLSH":"");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
tty = oldtty;
|
tty = oldtty;
|
||||||
|
|
||||||
tty.c_iflag = IGNBRK;
|
tty.c_iflag = n==3 ? (IXON|IXOFF) : IXOFF;
|
||||||
if (n == 3) { /* with flow control */
|
|
||||||
tty.c_iflag |= IXOFF; /* Enable XON/XOFF flow control on input */
|
|
||||||
tty.c_cflag |= CRTSCTS; /* hardware flowcontrol */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup raw mode: no echo, noncanonical (no edit chars),
|
* Setup raw mode: no echo, noncanonical (no edit chars),
|
||||||
* no signal generating chars, and no extended chars (^V,
|
* no signal generating chars, and no extended chars (^V,
|
||||||
* ^O, ^R, ^W).
|
* ^O, ^R, ^W).
|
||||||
*/
|
*/
|
||||||
tty.c_lflag = 0; /* Transparant input */
|
tty.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN);
|
||||||
tty.c_oflag = 0; /* Transparent output */
|
// tty.c_lflag = 0; /* Transparant input */
|
||||||
tty.c_cflag &= ~( CSIZE | CSTOPB | PARENB | PARODD); /* Same baud rate, disable parity */
|
tty.c_oflag = 0; /* Transparent output */
|
||||||
tty.c_cflag |= CS8 | CREAD | HUPCL | CLOCAL;
|
|
||||||
tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
|
tty.c_cflag &= ~( CSIZE | PARENB ); /* Same baud rate, disable parity */
|
||||||
tty.c_cc[VTIME] = 0;
|
tty.c_cflag |= CS8;
|
||||||
|
tty.c_cc[VMIN] = 2; /* This many chars satisfies reads */
|
||||||
|
tty.c_cc[VTIME] = 1;
|
||||||
tcsetattr(fd,TCSADRAIN,&tty);
|
tcsetattr(fd,TCSADRAIN,&tty);
|
||||||
Baudrate = getspeed(cfgetospeed(&tty));
|
Baudrate = getspeed(cfgetospeed(&tty));
|
||||||
Syslog('t', "Baudrate = %d", Baudrate);
|
Syslog('t', "Baudrate = %d", Baudrate);
|
||||||
|
did0 = TRUE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case 0:
|
case 0:
|
||||||
if (!did0)
|
if (!did0)
|
||||||
return -1;
|
return -1;
|
||||||
tcdrain (fd); /* wait until everything is sent */
|
tcdrain (fd); /* wait until everything is sent */
|
||||||
tcflush (fd,TCIOFLUSH); /* flush input queue */
|
tcflush (fd,TCIOFLUSH); /* flush input queue */
|
||||||
tcsetattr (fd,TCSADRAIN,&oldtty);
|
tcsetattr (fd,TCSADRAIN,&oldtty); /* Restore */
|
||||||
tcflow (fd,TCOON); /* restart output */
|
tcflow (fd,TCOON); /* restart output */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
@ -383,7 +386,7 @@ void sendbrk(void)
|
|||||||
|
|
||||||
if (isatty(0)) {
|
if (isatty(0)) {
|
||||||
#ifdef USE_TERMIOS
|
#ifdef USE_TERMIOS
|
||||||
tcsendbreak(0, 0);
|
tcsendbreak(0, 200);
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_TERMIO
|
#ifdef USE_TERMIO
|
||||||
ioctl(0, TCSBRK, 0);
|
ioctl(0, TCSBRK, 0);
|
||||||
|
107
mbsebbs/zmmisc.c
107
mbsebbs/zmmisc.c
@ -77,7 +77,6 @@ int Rxtimeout = 10; /* Seconds to wait for something, receiver */
|
|||||||
char *txbuf=NULL;
|
char *txbuf=NULL;
|
||||||
static int lastsent; /* Last char we sent */
|
static int lastsent; /* Last char we sent */
|
||||||
static int Not8bit; /* Seven bits seen on header */
|
static int Not8bit; /* Seven bits seen on header */
|
||||||
static char zsendline_tab[256];
|
|
||||||
|
|
||||||
extern unsigned Baudrate;
|
extern unsigned Baudrate;
|
||||||
extern int zmodem_requested;
|
extern int zmodem_requested;
|
||||||
@ -200,6 +199,9 @@ void zsbhdr(int type, char *shdr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BUFFER_FLUSH();
|
BUFFER_FLUSH();
|
||||||
|
|
||||||
|
if (type != ZDATA)
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -272,6 +274,7 @@ void zshhdr(int type, char *shdr)
|
|||||||
BUFFER_BYTE(021);
|
BUFFER_BYTE(021);
|
||||||
|
|
||||||
BUFFER_FLUSH();
|
BUFFER_FLUSH();
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -308,6 +311,9 @@ void zsdata(register char *buf, int length, int frameend)
|
|||||||
BUFFER_BYTE(XON);
|
BUFFER_BYTE(XON);
|
||||||
|
|
||||||
BUFFER_FLUSH();
|
BUFFER_FLUSH();
|
||||||
|
|
||||||
|
if (frameend != ZCRCG)
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -322,10 +328,7 @@ void zsda32(register char *buf, int length, int frameend)
|
|||||||
crc = 0xFFFFFFFFL;
|
crc = 0xFFFFFFFFL;
|
||||||
for (;--length >= 0; ++buf) {
|
for (;--length >= 0; ++buf) {
|
||||||
c = *buf & 0377;
|
c = *buf & 0377;
|
||||||
if (c & 0140)
|
zsendline(c);
|
||||||
BUFFER_BYTE(lastsent = c);
|
|
||||||
else
|
|
||||||
zsendline(c);
|
|
||||||
crc = updcrc32(c, crc);
|
crc = updcrc32(c, crc);
|
||||||
}
|
}
|
||||||
BUFFER_BYTE(ZDLE);
|
BUFFER_BYTE(ZDLE);
|
||||||
@ -476,7 +479,7 @@ void garbitch(void)
|
|||||||
int zgethdr(char *shdr)
|
int zgethdr(char *shdr)
|
||||||
{
|
{
|
||||||
register int c, n, cancount, tmcount;
|
register int c, n, cancount, tmcount;
|
||||||
int Zrwindow = 1024;
|
int Zrwindow = 1400;
|
||||||
|
|
||||||
n = Zrwindow + Baudrate;
|
n = Zrwindow + Baudrate;
|
||||||
Rxframeind = Rxtype = 0;
|
Rxframeind = Rxtype = 0;
|
||||||
@ -488,10 +491,11 @@ again:
|
|||||||
/*
|
/*
|
||||||
* Return immediate ERROR if ZCRCW sequence seen
|
* Return immediate ERROR if ZCRCW sequence seen
|
||||||
*/
|
*/
|
||||||
if (((c = GETCHAR(Rxtimeout)) < 0) && (c != TIMEOUT))
|
// if (((c = GETCHAR(Rxtimeout)) < 0) && (c != TIMEOUT))
|
||||||
goto fifi;
|
// goto fifi;
|
||||||
else {
|
// else {
|
||||||
switch(c) {
|
// switch(c) {
|
||||||
|
switch (c = GETCHAR(Rxtimeout)) {
|
||||||
case 021:
|
case 021:
|
||||||
case 0221: goto again;
|
case 0221: goto again;
|
||||||
case HANGUP: goto fifi;
|
case HANGUP: goto fifi;
|
||||||
@ -539,7 +543,7 @@ agn2:
|
|||||||
case ZPAD: /* This is what we want. */
|
case ZPAD: /* This is what we want. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
cancount = 5;
|
cancount = 5;
|
||||||
|
|
||||||
splat:
|
splat:
|
||||||
@ -566,7 +570,8 @@ splat:
|
|||||||
c = zrhhdr(shdr);
|
c = zrhhdr(shdr);
|
||||||
break;
|
break;
|
||||||
case CAN: goto gotcan;
|
case CAN: goto gotcan;
|
||||||
default: goto agn2;
|
default: Syslog('z', "Zmodem: zgethdr got %d char", c);
|
||||||
|
goto agn2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n = 4; ++n < ZMAXHLEN; ) /* Clear unused hdr bytes */
|
for (n = 4; ++n < ZMAXHLEN; ) /* Clear unused hdr bytes */
|
||||||
@ -739,68 +744,36 @@ void zputhex(int c)
|
|||||||
*/
|
*/
|
||||||
void zsendline(int c)
|
void zsendline(int c)
|
||||||
{
|
{
|
||||||
switch(zsendline_tab[(unsigned) (c&=0377)]) {
|
switch (c &= 0377) {
|
||||||
case 0: BUFFER_BYTE(lastsent = c);
|
case 0377:
|
||||||
break;
|
lastsent = c;
|
||||||
case 1: BUFFER_BYTE(ZDLE);
|
if (Zctlesc || Zsendmask[32]) {
|
||||||
c ^= 0100;
|
BUFFER_BYTE(ZDLE); c = ZRUB1;
|
||||||
BUFFER_BYTE(lastsent = c);
|
}
|
||||||
break;
|
BUFFER_BYTE(c);
|
||||||
case 2: if ((lastsent & 0177) != '@') {
|
break;
|
||||||
|
case ZDLE:
|
||||||
|
BUFFER_BYTE(ZDLE);
|
||||||
|
BUFFER_BYTE(lastsent = (c ^= 0100));
|
||||||
|
break;
|
||||||
|
case 021:
|
||||||
|
case 023:
|
||||||
|
case 0221:
|
||||||
|
case 0223:
|
||||||
|
BUFFER_BYTE(ZDLE);
|
||||||
|
c ^= 0100;
|
||||||
BUFFER_BYTE(lastsent = c);
|
BUFFER_BYTE(lastsent = c);
|
||||||
} else {
|
break;
|
||||||
BUFFER_BYTE(ZDLE);
|
default:
|
||||||
c ^= 0100;
|
if (((c & 0140) == 0) && (Zctlesc || Zsendmask[c & 037])) {
|
||||||
|
BUFFER_BYTE(ZDLE); c ^= 0100;
|
||||||
|
}
|
||||||
BUFFER_BYTE(lastsent = c);
|
BUFFER_BYTE(lastsent = c);
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void zsendline_init(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
Syslog('z', "zsendline_init() Zctlesc=%d", Zctlesc);
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
if (i & 0140)
|
|
||||||
zsendline_tab[i] = 0;
|
|
||||||
else {
|
|
||||||
switch(i) {
|
|
||||||
case ZDLE:
|
|
||||||
case XOFF: /* ^Q */
|
|
||||||
case XON: /* ^S */
|
|
||||||
case (XOFF | 0200):
|
|
||||||
case (XON | 0200):
|
|
||||||
zsendline_tab[i]=1;
|
|
||||||
break;
|
|
||||||
case 020: /* ^P */
|
|
||||||
case 0220:
|
|
||||||
zsendline_tab[i]=1;
|
|
||||||
break;
|
|
||||||
case 015:
|
|
||||||
case 0215:
|
|
||||||
if (Zctlesc)
|
|
||||||
zsendline_tab[i]=1;
|
|
||||||
else
|
|
||||||
zsendline_tab[i]=2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (Zctlesc)
|
|
||||||
zsendline_tab[i]=1;
|
|
||||||
else
|
|
||||||
zsendline_tab[i]=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// zsendline_tab[255] = 1; /* IAC */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Decode two lower case hex digits into an 8 bit byte value */
|
/* Decode two lower case hex digits into an 8 bit byte value */
|
||||||
int zgethex(void)
|
int zgethex(void)
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,14 @@
|
|||||||
#define ZBIN 'A' /* Binary frame indicator (CRC-16) */
|
#define ZBIN 'A' /* Binary frame indicator (CRC-16) */
|
||||||
#define ZHEX 'B' /* HEX frame indicator */
|
#define ZHEX 'B' /* HEX frame indicator */
|
||||||
#define ZBIN32 'C' /* Binary frame with 32 bit FCS */
|
#define ZBIN32 'C' /* Binary frame with 32 bit FCS */
|
||||||
|
#define ZBINR32 'D' /* RLE packed Binary frame with 32 bit FCS */
|
||||||
|
#define ZVBIN 'a' /* Binary frame indicator (CRC-16) */
|
||||||
|
#define ZVHEX 'b' /* HEX frame indicator */
|
||||||
|
#define ZVBIN32 'c' /* Binary frame with 32 bit FCS */
|
||||||
|
#define ZVBINR32 'd' /* RLE packed Binary frame with 32 bit FCS */
|
||||||
|
#define ZRESC 0176 /* RLE flag/escape character */
|
||||||
#define ZMAXHLEN 16 /* Max header information length NEVER CHANGE */
|
#define ZMAXHLEN 16 /* Max header information length NEVER CHANGE */
|
||||||
|
#define ZMAXSPLEN 1024 /* Max subpacket length NEVER CHANGE */
|
||||||
|
|
||||||
|
|
||||||
/* Frame types (see array "frametypes" in zm.c) */
|
/* Frame types (see array "frametypes" in zm.c) */
|
||||||
@ -75,19 +82,28 @@
|
|||||||
#define ZP3 3 /* High order 8 bits of file position */
|
#define ZP3 3 /* High order 8 bits of file position */
|
||||||
|
|
||||||
/* Parameters for ZRINIT header */
|
/* Parameters for ZRINIT header */
|
||||||
|
#define ZRPXWN 8 /* 9th byte in header contains window size/256 */
|
||||||
|
#define ZRPXQQ 9 /* 10th to 14th bytes contain quote mask */
|
||||||
|
|
||||||
/* Bit Masks for ZRINIT flags byte ZF0 */
|
/* Bit Masks for ZRINIT flags byte ZF0 */
|
||||||
#define CANFDX 01 /* Rx can send and receive true FDX */
|
#define CANFDX 01 /* Rx can send and receive true FDX */
|
||||||
#define CANOVIO 02 /* Rx can receive data during disk I/O */
|
#define CANOVIO 02 /* Rx can receive data during disk I/O */
|
||||||
#define CANBRK 04 /* Rx can send a break signal */
|
#define CANBRK 04 /* Rx can send a break signal */
|
||||||
|
#define CANRLE 010 /* Receiver can decode RLE */
|
||||||
#define CANLZW 020 /* Receiver can uncompress */
|
#define CANLZW 020 /* Receiver can uncompress */
|
||||||
#define CANFC32 040 /* Receiver can use 32 bit Frame Check */
|
#define CANFC32 040 /* Receiver can use 32 bit Frame Check */
|
||||||
#define ESCCTL 0100 /* Receiver expects ctl chars to be escaped */
|
#define ESCCTL 0100 /* Receiver expects ctl chars to be escaped */
|
||||||
#define ESC8 0200 /* Receiver expects 8th bit to be escaped */
|
#define ESC8 0200 /* Receiver expects 8th bit to be escaped */
|
||||||
|
|
||||||
/* Bit Masks for ZRINIT flags byte ZF1 */
|
/* Bit Masks for ZRINIT flags byte ZF1 */
|
||||||
|
#define CANVHDR 01 /* Variable headers OK */
|
||||||
|
#define ZRRQWN 8 /* Receiver specified window size in ZRPXWN */
|
||||||
|
#define ZRRQQQ 16 /* Additional control chars to quote in ZRPXQQ */
|
||||||
|
#define ZRQNVH (ZRRQWN|ZRRQQQ) /* Variable len hdr reqd to access info */
|
||||||
|
|
||||||
/* Parameters for ZSINIT frame */
|
/* Parameters for ZSINIT frame */
|
||||||
#define ZATTNLEN 32 /* Max length of attention string */
|
#define ZATTNLEN 32 /* Max length of attention string */
|
||||||
|
#define ALTCOFF ZF1 /* Offset to alternate canit string, 0 if not used */
|
||||||
/* Bit Masks for ZSINIT flags byte ZF0 */
|
/* Bit Masks for ZSINIT flags byte ZF0 */
|
||||||
#define TESCCTL 0100 /* Transmitter expects ctl chars to be escaped */
|
#define TESCCTL 0100 /* Transmitter expects ctl chars to be escaped */
|
||||||
#define TESC8 0200 /* Transmitter expects 8th bit to be escaped */
|
#define TESC8 0200 /* Transmitter expects 8th bit to be escaped */
|
||||||
@ -115,7 +131,9 @@
|
|||||||
#define ZTRLE 3 /* Run Length encoding */
|
#define ZTRLE 3 /* Run Length encoding */
|
||||||
/* Extended options for ZF3, bit encoded */
|
/* Extended options for ZF3, bit encoded */
|
||||||
#define ZXSPARS 64 /* Encoding for sparse file operations */
|
#define ZXSPARS 64 /* Encoding for sparse file operations */
|
||||||
|
#define ZCANVHDR 01 /* Variable headers OK */
|
||||||
/* Receiver window size override */
|
/* Receiver window size override */
|
||||||
|
#define ZRWOVR 4 /* byte position for receive window override/256 */
|
||||||
|
|
||||||
/* Parameters for ZCOMMAND frame ZF0 (otherwise 0) */
|
/* Parameters for ZCOMMAND frame ZF0 (otherwise 0) */
|
||||||
#define ZCACK1 1 /* Acknowledge, then do command */
|
#define ZCACK1 1 /* Acknowledge, then do command */
|
||||||
@ -134,7 +152,7 @@ char Rxhdr[ZMAXHLEN]; /* Received header */
|
|||||||
char Txhdr[ZMAXHLEN]; /* Transmitted header */
|
char Txhdr[ZMAXHLEN]; /* Transmitted header */
|
||||||
char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
|
char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
|
||||||
char *Altcan; /* Alternate canit string */
|
char *Altcan; /* Alternate canit string */
|
||||||
//char Zsendmask[33]; /* Additional control characters to mask */
|
char Zsendmask[33]; /* Additional control characters to mask */
|
||||||
int Zctlesc;
|
int Zctlesc;
|
||||||
|
|
||||||
enum zm_type_enum {
|
enum zm_type_enum {
|
||||||
@ -159,7 +177,6 @@ int zdlread(void);
|
|||||||
void stohdr(int);
|
void stohdr(int);
|
||||||
int rclhdr(register char *);
|
int rclhdr(register char *);
|
||||||
char *protname(void);
|
char *protname(void);
|
||||||
void zsendline_init(void);
|
|
||||||
void purgeline(int);
|
void purgeline(int);
|
||||||
void canit(int);
|
void canit(int);
|
||||||
|
|
||||||
|
@ -88,7 +88,6 @@ int zmrcvfiles(int want1k, int wantg)
|
|||||||
Syslog('+', "%s: start receive", protname());
|
Syslog('+', "%s: start receive", protname());
|
||||||
|
|
||||||
get_frame_buffer();
|
get_frame_buffer();
|
||||||
zsendline_init();
|
|
||||||
|
|
||||||
Rxtimeout = 10;
|
Rxtimeout = 10;
|
||||||
if (secbuf == NULL)
|
if (secbuf == NULL)
|
||||||
|
170
mbsebbs/zmsend.c
170
mbsebbs/zmsend.c
@ -47,6 +47,7 @@ static int zfilbuf(void);
|
|||||||
static int zsendfile(char*,int);
|
static int zsendfile(char*,int);
|
||||||
static int zsendfdata(void);
|
static int zsendfdata(void);
|
||||||
static int getinsync(int);
|
static int getinsync(int);
|
||||||
|
void initzsendmsk(char *p);
|
||||||
|
|
||||||
static FILE *in;
|
static FILE *in;
|
||||||
static int Eofseen; /* EOF seen on input set by zfilbuf */
|
static int Eofseen; /* EOF seen on input set by zfilbuf */
|
||||||
@ -61,14 +62,23 @@ static int blkopt; /* Override value for zmodem blklen */
|
|||||||
static int errors;
|
static int errors;
|
||||||
static int Lastsync;
|
static int Lastsync;
|
||||||
static int bytcnt;
|
static int bytcnt;
|
||||||
|
static int maxbytcnt;
|
||||||
static int Lrxpos=0;
|
static int Lrxpos=0;
|
||||||
static int Lztrans=0;
|
static int Lztrans=0;
|
||||||
static int Lzmanag=0;
|
static int Lzmanag=0;
|
||||||
static int Lskipnocor=0;
|
static int Lskipnocor=0;
|
||||||
static int Lzconv=0;
|
static int Lzconv=0;
|
||||||
static int Beenhereb4;
|
static int Beenhereb4;
|
||||||
static char Myattn[]={0};
|
static int Canseek = 1; /* 1: Can seek 0: only rewind -1: neither (pipe) */
|
||||||
|
/*
|
||||||
|
* Attention string to be executed by receiver to interrupt streaming data
|
||||||
|
* when an error is detected. A pause (0336) may be needed before the
|
||||||
|
* ^C (03) or after it.
|
||||||
|
*/
|
||||||
|
static char Myattn[]={ 0 };
|
||||||
static int skipsize;
|
static int skipsize;
|
||||||
|
static jmp_buf intrjmp; /* For the interrupt on RX CAN */
|
||||||
|
|
||||||
struct timeval starttime, endtime;
|
struct timeval starttime, endtime;
|
||||||
struct timezone tz;
|
struct timezone tz;
|
||||||
static int use8k = FALSE;
|
static int use8k = FALSE;
|
||||||
@ -81,6 +91,16 @@ extern char *frametypes[];
|
|||||||
extern unsigned Baudrate;
|
extern unsigned Baudrate;
|
||||||
|
|
||||||
|
|
||||||
|
/* Called when ZMODEM gets an interrupt (^X) */
|
||||||
|
void onintr(int );
|
||||||
|
void onintr(int c)
|
||||||
|
{
|
||||||
|
signal(SIGINT, SIG_IGN);
|
||||||
|
Syslog('z', "Zmodem: got signal interrupt");
|
||||||
|
longjmp(intrjmp, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int zmsndfiles(down_list *lst, int try8)
|
int zmsndfiles(down_list *lst, int try8)
|
||||||
{
|
{
|
||||||
int rc, maxrc = 0;
|
int rc, maxrc = 0;
|
||||||
@ -89,12 +109,12 @@ int zmsndfiles(down_list *lst, int try8)
|
|||||||
Syslog('+', "Zmodem: start Zmodem%s send", try8 ? "-8K":"");
|
Syslog('+', "Zmodem: start Zmodem%s send", try8 ? "-8K":"");
|
||||||
|
|
||||||
get_frame_buffer();
|
get_frame_buffer();
|
||||||
zsendline_init();
|
|
||||||
|
|
||||||
use8k = try8;
|
use8k = try8;
|
||||||
protocol = ZM_ZMODEM;
|
protocol = ZM_ZMODEM;
|
||||||
Rxtimeout = 60;
|
Rxtimeout = 60;
|
||||||
|
bytcnt = maxbytcnt = -1;
|
||||||
|
|
||||||
if ((rc = initsend())) {
|
if ((rc = initsend())) {
|
||||||
if (txbuf)
|
if (txbuf)
|
||||||
free(txbuf);
|
free(txbuf);
|
||||||
@ -132,7 +152,7 @@ int zmsndfiles(down_list *lst, int try8)
|
|||||||
free(txbuf);
|
free(txbuf);
|
||||||
txbuf = NULL;
|
txbuf = NULL;
|
||||||
del_frame_buffer();
|
del_frame_buffer();
|
||||||
// io_mode(0, 1);
|
io_mode(0, 1);
|
||||||
|
|
||||||
Syslog('z', "Zmodem: send rc=%d", maxrc);
|
Syslog('z', "Zmodem: send rc=%d", maxrc);
|
||||||
return (maxrc < 2)?0:maxrc;
|
return (maxrc < 2)?0:maxrc;
|
||||||
@ -144,7 +164,7 @@ static int initsend(void)
|
|||||||
{
|
{
|
||||||
Syslog('z', "Zmodem: initsend");
|
Syslog('z', "Zmodem: initsend");
|
||||||
|
|
||||||
// io_mode(0, 1);
|
io_mode(0, 1);
|
||||||
PUTSTR((char *)"rz\r");
|
PUTSTR((char *)"rz\r");
|
||||||
stohdr(0L);
|
stohdr(0L);
|
||||||
zshhdr(ZRQINIT, Txhdr);
|
zshhdr(ZRQINIT, Txhdr);
|
||||||
@ -266,19 +286,19 @@ int getzrxinit(void)
|
|||||||
case ZRINIT:
|
case ZRINIT:
|
||||||
Rxflags = 0377 & Rxhdr[ZF0];
|
Rxflags = 0377 & Rxhdr[ZF0];
|
||||||
Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
|
Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
|
||||||
{
|
Zctlesc |= Rxflags & TESCCTL;
|
||||||
int old = Zctlesc;
|
if (Rxhdr[ZF1] & ZRRQQQ) { /* Escape ctrls */
|
||||||
Zctlesc |= Rxflags & TESCCTL;
|
initzsendmsk(Rxhdr + ZRPXQQ);
|
||||||
/* update table - was initialised to not escape */
|
Syslog('z', "Zmodem: requested ZRPXQQ");
|
||||||
if (Zctlesc && !old)
|
|
||||||
zsendline_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
|
Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
|
||||||
if ( !(Rxflags & CANFDX))
|
if ( !(Rxflags & CANFDX))
|
||||||
Txwindow = 0;
|
Txwindow = 0;
|
||||||
Syslog('z', "Zmodem: Remote allowed Rxbuflen=%d", Rxbuflen);
|
Syslog('z', "Zmodem: Rxbuflen=%d", Rxbuflen);
|
||||||
// io_mode(0, 2); /* Set cbreak, XON/XOFF, etc. */
|
|
||||||
|
signal(SIGINT, SIG_IGN);
|
||||||
|
io_mode(0, 2); /* Set cbreak, XON/XOFF, etc. */
|
||||||
|
|
||||||
/* Set initial subpacket length */
|
/* Set initial subpacket length */
|
||||||
if (blklen < 1024) { /* Command line override? */
|
if (blklen < 1024) { /* Command line override? */
|
||||||
@ -288,6 +308,8 @@ int getzrxinit(void)
|
|||||||
blklen = 512;
|
blklen = 512;
|
||||||
if (Baudrate > 2400)
|
if (Baudrate > 2400)
|
||||||
blklen = 1024;
|
blklen = 1024;
|
||||||
|
if (Baudrate < 300)
|
||||||
|
blklen = 1024;
|
||||||
}
|
}
|
||||||
if (Rxbuflen && blklen>Rxbuflen)
|
if (Rxbuflen && blklen>Rxbuflen)
|
||||||
blklen = Rxbuflen;
|
blklen = Rxbuflen;
|
||||||
@ -337,7 +359,8 @@ int sendzsinit(void)
|
|||||||
} else
|
} else
|
||||||
zsbhdr(ZSINIT, Txhdr);
|
zsbhdr(ZSINIT, Txhdr);
|
||||||
Syslog('z', "sendzsinit Myattn \"%s\"", printable(Myattn, 0));
|
Syslog('z', "sendzsinit Myattn \"%s\"", printable(Myattn, 0));
|
||||||
zsdata(Myattn, 1 + strlen(Myattn), ZCRCW);
|
// zsdata(Myattn, 1 + strlen(Myattn), ZCRCW);
|
||||||
|
zsdata(Myattn, ZATTNLEN, ZCRCW);
|
||||||
c = zgethdr(Rxhdr);
|
c = zgethdr(Rxhdr);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ZCAN: return TERROR;
|
case ZCAN: return TERROR;
|
||||||
@ -375,9 +398,12 @@ int zfilbuf(void)
|
|||||||
*/
|
*/
|
||||||
int zsendfile(char *buf, int blen)
|
int zsendfile(char *buf, int blen)
|
||||||
{
|
{
|
||||||
int c;
|
int c, i, m, n;
|
||||||
register unsigned int crc = -1;
|
register unsigned int crc = -1;
|
||||||
int lastcrcrq = -1;
|
int lastcrcrq = -1;
|
||||||
|
int lastcrcof = -1;
|
||||||
|
int l;
|
||||||
|
char *p;
|
||||||
|
|
||||||
Syslog('z', "zsendfile %s (%d)", buf, blen);
|
Syslog('z', "zsendfile %s (%d)", buf, blen);
|
||||||
for (errors=0; ++errors<11;) {
|
for (errors=0; ++errors<11;) {
|
||||||
@ -414,15 +440,42 @@ again:
|
|||||||
case ZNAK:
|
case ZNAK:
|
||||||
continue;
|
continue;
|
||||||
case ZCRC:
|
case ZCRC:
|
||||||
if (Rxpos != lastcrcrq) {
|
l = Rxhdr[9] & 0377;
|
||||||
|
l = (l<<8) + (Rxhdr[8] & 0377);
|
||||||
|
l = (l<<8) + (Rxhdr[7] & 0377);
|
||||||
|
l = (l<<8) + (Rxhdr[6] & 0377);
|
||||||
|
if (Rxpos != lastcrcrq || l != lastcrcof) {
|
||||||
lastcrcrq = Rxpos;
|
lastcrcrq = Rxpos;
|
||||||
crc = 0xFFFFFFFFL;
|
crc = 0xFFFFFFFFL;
|
||||||
fseek(in, 0L, 0);
|
// fseek(in, 0L, 0);
|
||||||
while (((c = getc(in)) != EOF) && --lastcrcrq)
|
// while (((c = getc(in)) != EOF) && --lastcrcrq)
|
||||||
crc = updcrc32(c, crc);
|
// crc = updcrc32(c, crc);
|
||||||
crc = ~crc;
|
// crc = ~crc;
|
||||||
clearerr(in); /* Clear possible EOF */
|
// clearerr(in); /* Clear possible EOF */
|
||||||
lastcrcrq = Rxpos;
|
// lastcrcrq = Rxpos;
|
||||||
|
|
||||||
|
if (Canseek >= 0) {
|
||||||
|
fseek(in, bytcnt = l, 0); i = 0;
|
||||||
|
Syslog('z', "Zmodem: CRC32 on %ld bytes", Rxpos);
|
||||||
|
do {
|
||||||
|
/* No rx timeouts! */
|
||||||
|
if (--i < 0) {
|
||||||
|
i = 32768L/blklen;
|
||||||
|
PUTCHAR(SYN);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
bytcnt += m = n = zfilbuf();
|
||||||
|
if (bytcnt > maxbytcnt)
|
||||||
|
maxbytcnt = bytcnt;
|
||||||
|
for (p = txbuf; --m >= 0; ++p) {
|
||||||
|
c = *p & 0377;
|
||||||
|
crc = updcrc32(c, crc);
|
||||||
|
}
|
||||||
|
Syslog('z', "bytcnt=%d crc=%08X", bytcnt, crc);
|
||||||
|
} while (n && bytcnt < lastcrcrq);
|
||||||
|
crc = ~crc;
|
||||||
|
clearerr(in); /* Clear possible EOF */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stohdr(crc);
|
stohdr(crc);
|
||||||
zsbhdr(ZCRC, Txhdr);
|
zsbhdr(ZCRC, Txhdr);
|
||||||
@ -441,7 +494,7 @@ again:
|
|||||||
skipsize = Rxpos;
|
skipsize = Rxpos;
|
||||||
if (fseek(in, Rxpos, 0))
|
if (fseek(in, Rxpos, 0))
|
||||||
return TERROR;
|
return TERROR;
|
||||||
Lastsync = (bytcnt = Txpos = Lrxpos = Rxpos) -1;
|
Lastsync = (maxbytcnt = bytcnt = Txpos = Lrxpos = Rxpos) -1;
|
||||||
return zsendfdata();
|
return zsendfdata();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -471,7 +524,8 @@ int zsendfdata(void)
|
|||||||
junkcount = 0;
|
junkcount = 0;
|
||||||
Beenhereb4 = 0;
|
Beenhereb4 = 0;
|
||||||
somemore:
|
somemore:
|
||||||
if (0) {
|
// if (0) {
|
||||||
|
if (setjmp(intrjmp)) {
|
||||||
waitack:
|
waitack:
|
||||||
junkcount = 0;
|
junkcount = 0;
|
||||||
c = getinsync(0);
|
c = getinsync(0);
|
||||||
@ -486,18 +540,18 @@ gotack:
|
|||||||
return c;
|
return c;
|
||||||
case ZACK: Syslog('z', "zmsend: got ZACK");
|
case ZACK: Syslog('z', "zmsend: got ZACK");
|
||||||
break; // Possible bug, added 23-08-99
|
break; // Possible bug, added 23-08-99
|
||||||
case ZRPOS: blklen = ((blklen >> 2) > 64) ? (blklen >> 2) : 64;
|
case ZRPOS: /* blklen = ((blklen >> 2) > 64) ? (blklen >> 2) : 64;
|
||||||
goodblks = 0;
|
goodblks = 0;
|
||||||
goodneeded = ((goodneeded << 1) > 16) ? 16 : goodneeded << 1;
|
goodneeded = ((goodneeded << 1) > 16) ? 16 : goodneeded << 1;
|
||||||
Syslog('z', "zmsend: blocklen now %d", blklen);
|
Syslog('z', "zmsend: blocklen now %d", blklen); */
|
||||||
break;
|
break;
|
||||||
case TIMEOUT: /* Put back here 08-09-1999 mb */
|
// case TIMEOUT: /* Put back here 08-09-1999 mb */
|
||||||
Syslog('z', "zmsend: zsendfdata TIMEOUT");
|
// Syslog('z', "zmsend: zsendfdata TIMEOUT");
|
||||||
goto to;
|
// goto to;
|
||||||
case HANGUP: /* New, added 08-09-1999 mb */
|
// case HANGUP: /* New, added 08-09-1999 mb */
|
||||||
Syslog('z', "zmsend: zsendfdata HANGUP");
|
// Syslog('z', "zmsend: zsendfdata HANGUP");
|
||||||
fclose(in);
|
// fclose(in);
|
||||||
return c;
|
// return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -520,7 +574,9 @@ gotack:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
to:
|
//to:
|
||||||
|
|
||||||
|
signal(SIGINT, onintr);
|
||||||
newcnt = Rxbuflen;
|
newcnt = Rxbuflen;
|
||||||
Txwcnt = 0;
|
Txwcnt = 0;
|
||||||
stohdr(Txpos);
|
stohdr(Txpos);
|
||||||
@ -544,12 +600,14 @@ to:
|
|||||||
alarm_on();
|
alarm_on();
|
||||||
zsdata(txbuf, n, e);
|
zsdata(txbuf, n, e);
|
||||||
bytcnt = Txpos += n;
|
bytcnt = Txpos += n;
|
||||||
|
if (bytcnt > maxbytcnt)
|
||||||
|
maxbytcnt = bytcnt;
|
||||||
|
|
||||||
if ((blklen < maxblklen) && (++goodblks > goodneeded)) {
|
// if ((blklen < maxblklen) && (++goodblks > goodneeded)) {
|
||||||
blklen = ((blklen << 1) < maxblklen) ? blklen << 1 : maxblklen;
|
// blklen = ((blklen << 1) < maxblklen) ? blklen << 1 : maxblklen;
|
||||||
goodblks = 0;
|
// goodblks = 0;
|
||||||
Syslog('z', "zmsend: blocklen now %d", blklen);
|
// Syslog('z', "zmsend: blocklen now %d", blklen);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (e == ZCRCW)
|
if (e == ZCRCW)
|
||||||
goto waitack;
|
goto waitack;
|
||||||
@ -591,7 +649,8 @@ to:
|
|||||||
Syslog('z', "window = %ld", tcount);
|
Syslog('z', "window = %ld", tcount);
|
||||||
}
|
}
|
||||||
} while (!Eofseen);
|
} while (!Eofseen);
|
||||||
|
signal(SIGINT, SIG_IGN);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
stohdr(Txpos);
|
stohdr(Txpos);
|
||||||
zsbhdr(ZEOF, Txhdr);
|
zsbhdr(ZEOF, Txhdr);
|
||||||
@ -599,6 +658,7 @@ egotack:
|
|||||||
switch (getinsync(0)) {
|
switch (getinsync(0)) {
|
||||||
case ZACK: Syslog('z', "zsendfdata() ZACK");
|
case ZACK: Syslog('z', "zsendfdata() ZACK");
|
||||||
goto egotack; // continue in old source
|
goto egotack; // continue in old source
|
||||||
|
case ZNAK: continue;
|
||||||
case ZRPOS: goto somemore;
|
case ZRPOS: goto somemore;
|
||||||
case ZRINIT: fclose(in);
|
case ZRINIT: fclose(in);
|
||||||
return OK;
|
return OK;
|
||||||
@ -630,10 +690,17 @@ int getinsync(int flag)
|
|||||||
case ZCAN:
|
case ZCAN:
|
||||||
case ZABORT:
|
case ZABORT:
|
||||||
case ZFIN:
|
case ZFIN:
|
||||||
case TERROR:
|
/* case TERROR: */
|
||||||
case TIMEOUT: Syslog('+', "Zmodem: Got %s sending data", frametypes[c+FTOFFSET]);
|
case TIMEOUT: Syslog('+', "Zmodem: Got %s sending data", frametypes[c+FTOFFSET]);
|
||||||
return TERROR;
|
return TERROR;
|
||||||
case ZRPOS: /* ************************************* */
|
case ZRPOS: if (Rxpos > bytcnt) {
|
||||||
|
Syslog('z', "Zmodem: getinsync: Rxpos=%lx bytcnt=%lx Maxbytcnt=%lx",
|
||||||
|
Rxpos, bytcnt, maxbytcnt);
|
||||||
|
if (Rxpos > maxbytcnt)
|
||||||
|
Syslog('+', "Nonstandard Protocol at %lX", Rxpos);
|
||||||
|
return ZRPOS;
|
||||||
|
}
|
||||||
|
/* ************************************* */
|
||||||
/* If sending to a buffered modem, you */
|
/* If sending to a buffered modem, you */
|
||||||
/* might send a break at this point to */
|
/* might send a break at this point to */
|
||||||
/* dump the modem's buffer. */
|
/* dump the modem's buffer. */
|
||||||
@ -667,6 +734,7 @@ int getinsync(int flag)
|
|||||||
case ZRINIT: return c;
|
case ZRINIT: return c;
|
||||||
case ZSKIP: Syslog('+', "Zmodem: File skipped by receiver request");
|
case ZSKIP: Syslog('+', "Zmodem: File skipped by receiver request");
|
||||||
return c;
|
return c;
|
||||||
|
case TERROR:
|
||||||
default: zsbhdr(ZNAK, Txhdr);
|
default: zsbhdr(ZNAK, Txhdr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -674,3 +742,21 @@ int getinsync(int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set additional control chars to mask in Zsendmask
|
||||||
|
* according to bit array stored in char array at p
|
||||||
|
*/
|
||||||
|
void initzsendmsk(char *p)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
for (c = 0; c < 33; ++c) {
|
||||||
|
if (p [c >> 3] & (1 << (c & 7))) {
|
||||||
|
Zsendmask[c] = 1;
|
||||||
|
Syslog('z', "Zmodem: escaping %02o", c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user