Fixed the ymodem bugs, but most problems were caused by the buggy Dynacomm client

This commit is contained in:
Michiel Broek 2004-11-27 22:04:12 +00:00
parent 3e69bb2470
commit dd98697a34
8 changed files with 100 additions and 63 deletions

View File

@ -133,7 +133,7 @@ userlist.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h userlist.h
timestats.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h timestats.h funcs.h language.h input.h exitinfo.h term.h timestats.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h timestats.h funcs.h language.h input.h exitinfo.h term.h
logentry.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h logentry.h logentry.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h logentry.h
ymsend.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ttyio.h zmmisc.h transfer.h openport.h timeout.h term.h ymsend.h ymsend.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ttyio.h zmmisc.h transfer.h openport.h timeout.h term.h ymsend.h
ymrecv.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ttyio.h timeout.h zmmisc.h zmrecv.h ymrecv.h ymrecv.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ttyio.h timeout.h transfer.h zmmisc.h zmrecv.h ymsend.h ymrecv.h
zmmisc.o: ../config.h ../lib/mbselib.h ttyio.h input.h zmmisc.h zmmisc.o: ../config.h ../lib/mbselib.h ttyio.h input.h zmmisc.h
zmsend.o: ../config.h ../lib/mbselib.h ttyio.h zmmisc.h transfer.h openport.h timeout.h zmsend.o: ../config.h ../lib/mbselib.h ttyio.h zmmisc.h transfer.h openport.h timeout.h
zmrecv.o: ../config.h ../lib/mbselib.h ../lib/users.h ttyio.h transfer.h zmmisc.h zmrecv.h ymrecv.h openport.h timeout.h input.h zmrecv.o: ../config.h ../lib/mbselib.h ../lib/users.h ttyio.h transfer.h zmmisc.h zmrecv.h ymrecv.h openport.h timeout.h input.h

View File

@ -305,6 +305,8 @@ int download(down_list *download_list)
} }
closedir(dirp); closedir(dirp);
} }
purgeline(200); /* Wait a while, some Wintendo programs ignore input for a few seconds */
Altime(0); Altime(0);
alarm_off(); alarm_off();
alarm_on(); alarm_on();
@ -389,7 +391,7 @@ int upload(up_list **upload_list)
struct timeval starttime, endtime; struct timeval starttime, endtime;
struct timezone tz; struct timezone tz;
unsigned long Size = 0; unsigned long Size = 0;
int err, Count = 0, rc = 0, want1k = FALSE; int err, Count = 0, rc = 0, want1k = FALSE, wantg = FALSE;
up_list *tmp, *ta; up_list *tmp, *ta;
/* /*
@ -417,7 +419,10 @@ int upload(up_list **upload_list)
sleep(2); sleep(2);
if (uProtInternal) { if (uProtInternal) {
if ((strncasecmp(sProtName, "zmodem", 6) == 0) || (strncasecmp(sProtName, "ymodem", 6) == 0)) { if ((strncasecmp(sProtName, "zmodem", 6) == 0) ||
(strncasecmp(sProtName, "ymodem", 6) == 0) ||
(strncasecmp(sProtName, "xmodem", 6) == 0)) {
if (strncasecmp(sProtName, "zmodem", 6) == 0) { if (strncasecmp(sProtName, "zmodem", 6) == 0) {
zmodem_requested = TRUE; zmodem_requested = TRUE;
protocol = ZM_ZMODEM; protocol = ZM_ZMODEM;
@ -426,10 +431,18 @@ int upload(up_list **upload_list)
} }
if (strncasecmp(sProtName, "ymodem", 6) == 0) if (strncasecmp(sProtName, "ymodem", 6) == 0)
protocol = ZM_YMODEM; protocol = ZM_YMODEM;
if (strncasecmp(sProtName, "xmodem", 6) == 0)
protocol = ZM_XMODEM;
if (strstr(sProtName, "1K") || strstr(sProtName, "1k")) if ((strstr(sProtName, "1K") || strstr(sProtName, "1k")) && (protocol != ZM_ZMODEM)) {
Syslog('x', "%s: want 1K blocks", protname());
want1k = TRUE; want1k = TRUE;
rc = zmrcvfiles(want1k); }
if ((strstr(sProtName, "G")) && (protocol == ZM_YMODEM)) {
Syslog('x', "%s: want Ymodem-G", protname());
wantg = TRUE;
}
rc = zmrcvfiles(want1k, wantg);
Syslog('b', "Begin dir processing"); Syslog('b', "Begin dir processing");
if ((dirp = opendir(".")) == NULL) { if ((dirp = opendir(".")) == NULL) {

View File

@ -33,8 +33,10 @@
#include "../lib/mbse.h" #include "../lib/mbse.h"
#include "ttyio.h" #include "ttyio.h"
#include "timeout.h" #include "timeout.h"
#include "transfer.h"
#include "zmmisc.h" #include "zmmisc.h"
#include "zmrecv.h" #include "zmrecv.h"
#include "ymsend.h"
#include "ymrecv.h" #include "ymrecv.h"
@ -42,6 +44,8 @@
static int Firstsec; static int Firstsec;
static int eof_seen; static int eof_seen;
static int errors; static int errors;
static int Gflg = FALSE;
static char NAKchar;
extern long Bytesleft; extern long Bytesleft;
extern off_t rxbytes; extern off_t rxbytes;
@ -50,22 +54,38 @@ extern char Lastrx;
extern char *secbuf; extern char *secbuf;
#define sendline(c) PUTCHAR((c) & 0377) #define sendline(c) PUTCHAR((c & 0377))
int wcgetsec(size_t *, char *, unsigned int); int wcgetsec(size_t *, char *, unsigned int);
int wcrxpn(char *, int); int wcrxpn(char *);
int wcrx(void); int wcrx(void);
int ymrcvfiles(int want1k) int ymrcvfiles(int want1k, int wantG)
{ {
int rc = 0; int rc = 0;
Syslog('x', "%s: ymrcvfiles(%s)", protname(), want1k ? "TRUE":"FALSE"); NAKchar = NAK;
Crcflg = Gflg = FALSE;
if (protocol == ZM_YMODEM) {
NAKchar = WANTCRC;
Crcflg = TRUE;
}
if (want1k) {
Crcflg = TRUE;
NAKchar = WANTCRC;
}
if (wantG) {
Crcflg = Gflg = TRUE;
NAKchar = WANTG;
}
Syslog('x', "%s: ymrcvfiles(%s, %s)", protname(), want1k ? "TRUE":"FALSE", wantG ? "TRUE":"FALSE");
Syslog('x', "%s: NAK character will be %s", protname(), printablec(NAKchar));
for (;;) { for (;;) {
rxbytes = 0l; rxbytes = 0l;
if (wcrxpn(secbuf, want1k) == TERROR) { if (wcrxpn(secbuf) == TERROR) {
rc = 2; rc = 2;
break; break;
} }
@ -95,26 +115,26 @@ int ymrcvfiles(int want1k)
* Length is indeterminate as long as less than Blklen * Length is indeterminate as long as less than Blklen
* A null string represents no more files (YMODEM) * A null string represents no more files (YMODEM)
*/ */
int wcrxpn(char *rpn, int want1k) int wcrxpn(char *rpn)
{ {
register int c; register int c;
size_t Blklen = 0; /* record length of received packets */ size_t Blklen = 0; /* record length of received packets */
Crcflg = want1k;
purgeline(0); purgeline(0);
Syslog('x', "%s: wcrxpn() crc=%s", protname(), Crcflg ? "true":"false"); Syslog('x', "%s: wcrxpn() crc=%s", protname(), Crcflg ? "true":"false");
et_tu: et_tu:
Firstsec = TRUE; Firstsec = TRUE;
eof_seen = FALSE; eof_seen = FALSE;
sendline(Crcflg?WANTCRC:NAK); Syslog('x', "Send %s", printablec(NAKchar));
ioctl(1, TCFLSH, 0); sendline(NAKchar);
// ioctl(1, TCFLSH, 0);
purgeline(0); /* Do read next time ... */ purgeline(0); /* Do read next time ... */
while ((c = wcgetsec(&Blklen, rpn, 10)) != 0) { while ((c = wcgetsec(&Blklen, rpn, 10)) != 0) {
if (c == WCEOT) { if (c == WCEOT) {
Syslog('x', "Pathname fetch returned EOT"); Syslog('x', "Pathname fetch returned EOT");
sendline(ACK); sendline(ACK);
ioctl(1, TCFLSH, 0); // ioctl(1, TCFLSH, 0);
purgeline(0); /* Do read next time ... */ purgeline(0); /* Do read next time ... */
goto et_tu; goto et_tu;
} }
@ -136,13 +156,13 @@ int wcrx(void)
Firstsec = TRUE; sectnum = 0; Firstsec = TRUE; sectnum = 0;
eof_seen = FALSE; eof_seen = FALSE;
sendchar = Crcflg ? WANTCRC:NAK; sendchar = NAKchar;
Syslog('x', "%s: wcrx", protname()); Syslog('x', "%s: wcrx, request type %s", protname(), printablec(sendchar));
for (;;) { for (;;) {
sendline(sendchar); /* send it now, we're ready! */ sendline(sendchar); /* send it now, we're ready! */
ioctl(1, TCFLSH, 0); // ioctl(1, TCFLSH, 0);
purgeline(0); /* Do read next time ... */ purgeline(0); /* Do read next time ... */
/* /*
@ -164,19 +184,18 @@ int wcrx(void)
if (putsec(secbuf, Blklen) == ERROR) if (putsec(secbuf, Blklen) == ERROR)
return ERROR; return ERROR;
sendchar = ACK; sendchar = ACK;
} } else if (sectcurr == (sectnum & 0377)) {
else if (sectcurr == (sectnum & 0377)) {
Syslog('x', "Received dup Sector"); Syslog('x', "Received dup Sector");
sendchar = ACK; sendchar = ACK;
} else if (sectcurr == WCEOT) { } else if (sectcurr == WCEOT) {
if (closeit(1)) if (closeit(1))
return ERROR; return ERROR;
sendline(ACK); sendline(ACK);
ioctl(1, TCFLSH, 0); // ioctl(1, TCFLSH, 0);
purgeline(0); /* Do read next time ... */ purgeline(0); /* Do read next time ... */
return OK; return OK;
} }
else if (sectcurr == ERROR) else if (sectcurr == TERROR)
return ERROR; return ERROR;
else { else {
Syslog('x', "Sync Error"); Syslog('x', "Sync Error");
@ -202,6 +221,7 @@ int wcgetsec(size_t *Blklen, char *rxbuf, unsigned int maxtime)
if (firstch == SOH) { if (firstch == SOH) {
*Blklen=128; *Blklen=128;
get2: get2:
Syslog('x', "wcgetsec: firstch=%s, maxtime=%d, check=%s", printablec(firstch), maxtime, Crcflg?"CRC":"Checksum");
sectcurr = GETCHAR(1); sectcurr = GETCHAR(1);
if ((sectcurr + (oldcrc = GETCHAR(1))) == 0377) { if ((sectcurr + (oldcrc = GETCHAR(1))) == 0377) {
oldcrc = Checksum = 0; oldcrc = Checksum = 0;
@ -237,8 +257,8 @@ get2:
return WCEOT; return WCEOT;
else if (firstch == CAN) { else if (firstch == CAN) {
if (Lastrx == CAN) { if (Lastrx == CAN) {
Syslog('x', "Sender Cancelled"); Syslog('+', "%s: sender Cancelled during transfer", protname());
return ERROR; return TERROR;
} else { } else {
Lastrx=CAN; Lastrx=CAN;
continue; continue;
@ -258,21 +278,21 @@ humbug:
} }
if (Firstsec) { if (Firstsec) {
sendline(Crcflg ? WANTCRC:NAK); sendline(NAKchar);
ioctl(1, TCFLSH, 0); // ioctl(1, TCFLSH, 0);
Syslog('x', "%s: send %s", protname(), Crcflg ? "WANTCRC":"NAK"); Syslog('x', "%s: send %s", protname(), printablec(NAKchar));
purgeline(0); /* Do read next time ... */ purgeline(0); /* Do read next time ... */
} else { } else {
maxtime = 40; maxtime = 5;
sendline(NAK); sendline(NAK);
Syslog('x', "%s: send NAK", protname()); Syslog('x', "%s: send NAK", protname());
ioctl(1, TCFLSH, 0); // ioctl(1, TCFLSH, 0);
purgeline(0); /* Do read next time ... */ purgeline(0); /* Do read next time ... */
} }
} }
/* try to stop the bubble machine. */ /* try to stop the bubble machine. */
canit(STDOUT_FILENO); canit(STDOUT_FILENO);
return ERROR; return TERROR;
} }

View File

@ -3,13 +3,12 @@
/* $Id$ */ /* $Id$ */
#define WANTCRC 0103 /* send C not NAK to get crc not checksum */
#define WCEOT (-10) #define WCEOT (-10)
#define RETRYMAX 10 #define RETRYMAX 10
int ymrcvfiles(int); int ymrcvfiles(int, int);
#endif #endif

View File

@ -41,7 +41,7 @@
#define MAX_BLOCK 8192 #define MAX_BLOCK 8192
#define sendline(c) PUTCHAR((c) & 0377) #define sendline(c) PUTCHAR((c & 0377))
FILE *input_f; FILE *input_f;
@ -94,6 +94,13 @@ int ymsndfiles(down_list *lst, int use1k)
} }
Syslog('x', "%s: %d files, size %d bytes", protname(), Filesleft, Totalleft); Syslog('x', "%s: %d files, size %d bytes", protname(), Filesleft, Totalleft);
/*
* This is not documented as auto start sequence, but a lot of terminal
* programs seem to react on this.
*/
if (protocol == ZM_YMODEM)
PUTSTR((char *)"rb\r");
for (tmpf = lst; tmpf && (maxrc < 2); tmpf = tmpf->next) { for (tmpf = lst; tmpf && (maxrc < 2); tmpf = tmpf->next) {
if (tmpf->remote) { if (tmpf->remote) {
bytes_sent = 0; bytes_sent = 0;
@ -217,6 +224,7 @@ static int wctxpn(char *fname)
if ((input_f != stdin) && *fname) if ((input_f != stdin) && *fname)
sprintf(p, "%lu %lo %o 0 %d %ld", (long) f.st_size, f.st_mtime, sprintf(p, "%lu %lo %o 0 %d %ld", (long) f.st_size, f.st_mtime,
(unsigned int)((no_unixmode) ? 0 : f.st_mode), Filesleft, Totalleft); (unsigned int)((no_unixmode) ? 0 : f.st_mode), Filesleft, Totalleft);
// sprintf(p, "%lu %lo 0 0 0 0", (long) f.st_size, f.st_mtime);
Totalleft -= f.st_size; Totalleft -= f.st_size;
if (--Filesleft <= 0) if (--Filesleft <= 0)
@ -224,18 +232,9 @@ static int wctxpn(char *fname)
if (Totalleft < 0) if (Totalleft < 0)
Totalleft = 0; Totalleft = 0;
/* force 1k blocks if name won't fit in 128 byte block */ purgeline(1);
if (txbuf[125])
blklen=1024;
else { /* A little goodie for IMP/KMD */
txbuf[127] = (f.st_size + 127) >>7;
txbuf[126] = (f.st_size + 127) >>15;
}
// if (zmodem_requested)
// return zsendfile(zi,txbuf, 1+strlen(p)+(p-txbuf));
if (wcputsec(txbuf, 0, 128) == TERROR) { if (wcputsec(txbuf, 0, 128) == TERROR) {
PUTSTR((char *)"wcputsec failed"); Syslog('+', "%s: failed to send filename", protname());
Syslog('+', "%s/%s: wcputsec failed", fname,protname());
return TERROR; return TERROR;
} }
return OK; return OK;
@ -243,6 +242,9 @@ static int wctxpn(char *fname)
/*
* Get NAK, C or G
*/
static int getnak(void) static int getnak(void)
{ {
int firstch; int firstch;
@ -261,7 +263,7 @@ static int getnak(void)
// return FALSE; // return FALSE;
case TIMEOUT: case TIMEOUT:
Syslog('x', "getnak: timeout try %d", tries); Syslog('x', "getnak: timeout try %d", tries);
/* 50 seconds are enough */ /* 50 seconds are enough (was 30, 26-11-2004 MB) */
if (tries == 5) { if (tries == 5) {
Syslog('x', "Timeout on pathname"); Syslog('x', "Timeout on pathname");
return TRUE; return TRUE;
@ -283,16 +285,21 @@ static int getnak(void)
io_mode(0, 2); /* Set cbreak, XON/XOFF, etc. */ io_mode(0, 2); /* Set cbreak, XON/XOFF, etc. */
Optiong = TRUE; Optiong = TRUE;
blklen=1024; blklen=1024;
Crcflg = TRUE;
return FALSE;
case WANTCRC: case WANTCRC:
Syslog('x', "getnak: got WANTCRC"); Syslog('x', "getnak: got WANTCRC");
Crcflg = TRUE; Crcflg = TRUE;
return FALSE;
case NAK: case NAK:
Syslog('x', "getnak: got NAK"); Syslog('x', "getnak: got NAK");
return FALSE; return FALSE;
case CAN: case CAN:
Syslog('x', "getnak: got CAN"); Syslog('x', "getnak: got CAN");
if ((firstch = GETCHAR(2)) == CAN && Lastrx == CAN) if ((firstch = GETCHAR(2)) == CAN && Lastrx == CAN) {
Syslog('+', "%s: Receiver cancelled", protname());
return TRUE; return TRUE;
}
default: default:
Syslog('x', "got %d", firstch); Syslog('x', "got %d", firstch);
break; break;
@ -316,7 +323,7 @@ static int wctx(long bytes_total)
while ((firstch = GETCHAR(Rxtimeout)) != NAK && firstch != WANTCRC while ((firstch = GETCHAR(Rxtimeout)) != NAK && firstch != WANTCRC
&& firstch != WANTG && firstch != TIMEOUT && firstch != CAN); && firstch != WANTG && firstch != TIMEOUT && firstch != CAN);
if (firstch == CAN) { if (firstch == CAN) {
Syslog('x', "Receiver Cancelled"); Syslog('+', "%s: receiver Cancelled during transfer", protname());
return TERROR; return TERROR;
} }
@ -348,7 +355,6 @@ static int wctx(long bytes_total)
do { do {
purgeline(5); purgeline(5);
PUTCHAR(EOT); PUTCHAR(EOT);
ioctl(1, TCFLSH, 0);
++attempts; ++attempts;
} while ((firstch = (GETCHAR(Rxtimeout)) != ACK) && attempts < RETRYMAX); } while ((firstch = (GETCHAR(Rxtimeout)) != ACK) && attempts < RETRYMAX);
if (attempts == RETRYMAX) { if (attempts == RETRYMAX) {
@ -373,11 +379,10 @@ static int wcputsec(char *buf, int sectnum, size_t cseclen)
Syslog('x', "%s: wcputsec: sectnum %d, len %d, %s", protname(), sectnum, cseclen, Crcflg ? "crc":"checksum"); Syslog('x', "%s: wcputsec: sectnum %d, len %d, %s", protname(), sectnum, cseclen, Crcflg ? "crc":"checksum");
for (attempts = 0; attempts <= RETRYMAX; attempts++) { for (attempts = 0; attempts <= RETRYMAX; attempts++) {
Syslog('x', "send sector");
Lastrx = firstch; Lastrx = firstch;
sendline(cseclen == 1024 ? STX:SOH); sendline(cseclen == 1024 ? STX:SOH);
sendline(sectnum); sendline(sectnum);
sendline(-sectnum -1); sendline((-sectnum -1));
oldcrc = Checksum = 0; oldcrc = Checksum = 0;
for (wcj = cseclen, cp = buf; --wcj >= 0; ) { for (wcj = cseclen, cp = buf; --wcj >= 0; ) {
sendline(*cp); sendline(*cp);
@ -388,11 +393,10 @@ static int wcputsec(char *buf, int sectnum, size_t cseclen)
oldcrc = updcrc16(0, updcrc16(0, oldcrc)); oldcrc = updcrc16(0, updcrc16(0, oldcrc));
sendline((int)oldcrc >> 8); sendline((int)oldcrc >> 8);
sendline((int)oldcrc); sendline((int)oldcrc);
} } else {
else
sendline(Checksum); sendline(Checksum);
}
ioctl(1, TCFLSH, 0);
if (Optiong) { if (Optiong) {
firstsec = FALSE; firstsec = FALSE;
return OK; return OK;
@ -416,10 +420,9 @@ cancan:
Crcflg = TRUE; Crcflg = TRUE;
case NAK: case NAK:
Syslog('+', "%s: got NAK on sector %d", protname(), sectnum); Syslog('+', "%s: got NAK on sector %d", protname(), sectnum);
purgeline(10); purgeline(20);
continue; continue;
case ACK: case ACK:
Syslog('x', "Got ACK");
firstsec=FALSE; firstsec=FALSE;
Totsecs += (cseclen>>7); Totsecs += (cseclen>>7);
return OK; return OK;

View File

@ -5,9 +5,9 @@
#define RETRYMAX 10 #define RETRYMAX 10
#define CPMEOF 032 #define CPMEOF 032 /* CP/M EOF, Ctrl-Z */
#define WANTCRC 0103 /* send C not NAK to get crc not checksum */ #define WANTCRC 'C' /* send C not NAK to get crc not checksum */
#define WANTG 0107 /* Send G not NAK to get nonstop batch xmsn */ #define WANTG 'G' /* Send G not NAK to get nonstop batch xmsn */
int ymsndfiles(down_list *, int); int ymsndfiles(down_list *, int);

View File

@ -80,7 +80,7 @@ extern int zmodem_requested;
* This receiver will figure out what to do, you should * This receiver will figure out what to do, you should
* be able to send anything. * be able to send anything.
*/ */
int zmrcvfiles(int want1k) int zmrcvfiles(int want1k, int wantg)
{ {
int rc; int rc;
@ -99,7 +99,7 @@ int zmrcvfiles(int want1k)
Syslog('+', "%s: switching to Ymodem", protname()); Syslog('+', "%s: switching to Ymodem", protname());
protocol = ZM_YMODEM; protocol = ZM_YMODEM;
} }
rc = ymrcvfiles(want1k); rc = ymrcvfiles(want1k, wantg);
goto fubar; goto fubar;
} }
@ -128,8 +128,10 @@ fubar:
io_mode(0, 1); /* Normal raw mode */ io_mode(0, 1); /* Normal raw mode */
/* /*
* Some programs send some garbage after the transfer, eat these. * Some programs send some garbage after the transfer, eat these.
* This also introduces a pause after the transfer, some clients
* need this.
*/ */
purgeline(100); purgeline(200);
Syslog('+', "%s: end receive rc=%d", protname(), rc); Syslog('+', "%s: end receive rc=%d", protname(), rc);
return abs(rc); return abs(rc);
@ -151,7 +153,7 @@ int tryz(void)
if (protocol != ZM_ZMODEM) if (protocol != ZM_ZMODEM)
return 0; return 0;
for (n = zmodem_requested ?15:5; --n >= 0; ) { for (n = zmodem_requested ?15:10; --n >= 0; ) {
/* /*
* Set buffer length (0) and capability flags * Set buffer length (0) and capability flags
*/ */

View File

@ -4,7 +4,7 @@
/* $Id$ */ /* $Id$ */
int procheader(char*); int procheader(char*);
int zmrcvfiles(int); int zmrcvfiles(int, int);
int putsec(char*,int); int putsec(char*,int);
int closeit(int); int closeit(int);