Fixed the ymodem bugs, but most problems were caused by the buggy Dynacomm client
This commit is contained in:
parent
3e69bb2470
commit
dd98697a34
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -305,6 +305,8 @@ int download(down_list *download_list)
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
purgeline(200); /* Wait a while, some Wintendo programs ignore input for a few seconds */
|
||||
Altime(0);
|
||||
alarm_off();
|
||||
alarm_on();
|
||||
@ -389,7 +391,7 @@ int upload(up_list **upload_list)
|
||||
struct timeval starttime, endtime;
|
||||
struct timezone tz;
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -417,7 +419,10 @@ int upload(up_list **upload_list)
|
||||
sleep(2);
|
||||
|
||||
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) {
|
||||
zmodem_requested = TRUE;
|
||||
protocol = ZM_ZMODEM;
|
||||
@ -426,10 +431,18 @@ int upload(up_list **upload_list)
|
||||
}
|
||||
if (strncasecmp(sProtName, "ymodem", 6) == 0)
|
||||
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;
|
||||
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");
|
||||
if ((dirp = opendir(".")) == NULL) {
|
||||
|
@ -33,8 +33,10 @@
|
||||
#include "../lib/mbse.h"
|
||||
#include "ttyio.h"
|
||||
#include "timeout.h"
|
||||
#include "transfer.h"
|
||||
#include "zmmisc.h"
|
||||
#include "zmrecv.h"
|
||||
#include "ymsend.h"
|
||||
#include "ymrecv.h"
|
||||
|
||||
|
||||
@ -42,6 +44,8 @@
|
||||
static int Firstsec;
|
||||
static int eof_seen;
|
||||
static int errors;
|
||||
static int Gflg = FALSE;
|
||||
static char NAKchar;
|
||||
|
||||
extern long Bytesleft;
|
||||
extern off_t rxbytes;
|
||||
@ -50,22 +54,38 @@ extern char Lastrx;
|
||||
extern char *secbuf;
|
||||
|
||||
|
||||
#define sendline(c) PUTCHAR((c) & 0377)
|
||||
#define sendline(c) PUTCHAR((c & 0377))
|
||||
|
||||
int wcgetsec(size_t *, char *, unsigned int);
|
||||
int wcrxpn(char *, int);
|
||||
int wcrxpn(char *);
|
||||
int wcrx(void);
|
||||
|
||||
|
||||
int ymrcvfiles(int want1k)
|
||||
int ymrcvfiles(int want1k, int wantG)
|
||||
{
|
||||
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 (;;) {
|
||||
rxbytes = 0l;
|
||||
if (wcrxpn(secbuf, want1k) == TERROR) {
|
||||
if (wcrxpn(secbuf) == TERROR) {
|
||||
rc = 2;
|
||||
break;
|
||||
}
|
||||
@ -95,26 +115,26 @@ int ymrcvfiles(int want1k)
|
||||
* Length is indeterminate as long as less than Blklen
|
||||
* A null string represents no more files (YMODEM)
|
||||
*/
|
||||
int wcrxpn(char *rpn, int want1k)
|
||||
int wcrxpn(char *rpn)
|
||||
{
|
||||
register int c;
|
||||
size_t Blklen = 0; /* record length of received packets */
|
||||
|
||||
Crcflg = want1k;
|
||||
purgeline(0);
|
||||
Syslog('x', "%s: wcrxpn() crc=%s", protname(), Crcflg ? "true":"false");
|
||||
|
||||
et_tu:
|
||||
Firstsec = TRUE;
|
||||
eof_seen = FALSE;
|
||||
sendline(Crcflg?WANTCRC:NAK);
|
||||
ioctl(1, TCFLSH, 0);
|
||||
Syslog('x', "Send %s", printablec(NAKchar));
|
||||
sendline(NAKchar);
|
||||
// ioctl(1, TCFLSH, 0);
|
||||
purgeline(0); /* Do read next time ... */
|
||||
while ((c = wcgetsec(&Blklen, rpn, 10)) != 0) {
|
||||
if (c == WCEOT) {
|
||||
Syslog('x', "Pathname fetch returned EOT");
|
||||
sendline(ACK);
|
||||
ioctl(1, TCFLSH, 0);
|
||||
// ioctl(1, TCFLSH, 0);
|
||||
purgeline(0); /* Do read next time ... */
|
||||
goto et_tu;
|
||||
}
|
||||
@ -136,13 +156,13 @@ int wcrx(void)
|
||||
|
||||
Firstsec = TRUE; sectnum = 0;
|
||||
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 (;;) {
|
||||
sendline(sendchar); /* send it now, we're ready! */
|
||||
ioctl(1, TCFLSH, 0);
|
||||
// ioctl(1, TCFLSH, 0);
|
||||
purgeline(0); /* Do read next time ... */
|
||||
|
||||
/*
|
||||
@ -164,19 +184,18 @@ int wcrx(void)
|
||||
if (putsec(secbuf, Blklen) == ERROR)
|
||||
return ERROR;
|
||||
sendchar = ACK;
|
||||
}
|
||||
else if (sectcurr == (sectnum & 0377)) {
|
||||
} else if (sectcurr == (sectnum & 0377)) {
|
||||
Syslog('x', "Received dup Sector");
|
||||
sendchar = ACK;
|
||||
} else if (sectcurr == WCEOT) {
|
||||
if (closeit(1))
|
||||
return ERROR;
|
||||
sendline(ACK);
|
||||
ioctl(1, TCFLSH, 0);
|
||||
// ioctl(1, TCFLSH, 0);
|
||||
purgeline(0); /* Do read next time ... */
|
||||
return OK;
|
||||
}
|
||||
else if (sectcurr == ERROR)
|
||||
else if (sectcurr == TERROR)
|
||||
return ERROR;
|
||||
else {
|
||||
Syslog('x', "Sync Error");
|
||||
@ -202,6 +221,7 @@ int wcgetsec(size_t *Blklen, char *rxbuf, unsigned int maxtime)
|
||||
if (firstch == SOH) {
|
||||
*Blklen=128;
|
||||
get2:
|
||||
Syslog('x', "wcgetsec: firstch=%s, maxtime=%d, check=%s", printablec(firstch), maxtime, Crcflg?"CRC":"Checksum");
|
||||
sectcurr = GETCHAR(1);
|
||||
if ((sectcurr + (oldcrc = GETCHAR(1))) == 0377) {
|
||||
oldcrc = Checksum = 0;
|
||||
@ -237,8 +257,8 @@ get2:
|
||||
return WCEOT;
|
||||
else if (firstch == CAN) {
|
||||
if (Lastrx == CAN) {
|
||||
Syslog('x', "Sender Cancelled");
|
||||
return ERROR;
|
||||
Syslog('+', "%s: sender Cancelled during transfer", protname());
|
||||
return TERROR;
|
||||
} else {
|
||||
Lastrx=CAN;
|
||||
continue;
|
||||
@ -258,21 +278,21 @@ humbug:
|
||||
}
|
||||
|
||||
if (Firstsec) {
|
||||
sendline(Crcflg ? WANTCRC:NAK);
|
||||
ioctl(1, TCFLSH, 0);
|
||||
Syslog('x', "%s: send %s", protname(), Crcflg ? "WANTCRC":"NAK");
|
||||
sendline(NAKchar);
|
||||
// ioctl(1, TCFLSH, 0);
|
||||
Syslog('x', "%s: send %s", protname(), printablec(NAKchar));
|
||||
purgeline(0); /* Do read next time ... */
|
||||
} else {
|
||||
maxtime = 40;
|
||||
maxtime = 5;
|
||||
sendline(NAK);
|
||||
Syslog('x', "%s: send NAK", protname());
|
||||
ioctl(1, TCFLSH, 0);
|
||||
// ioctl(1, TCFLSH, 0);
|
||||
purgeline(0); /* Do read next time ... */
|
||||
}
|
||||
}
|
||||
/* try to stop the bubble machine. */
|
||||
canit(STDOUT_FILENO);
|
||||
return ERROR;
|
||||
return TERROR;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,13 +3,12 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#define WANTCRC 0103 /* send C not NAK to get crc not checksum */
|
||||
#define WCEOT (-10)
|
||||
|
||||
#define RETRYMAX 10
|
||||
|
||||
|
||||
int ymrcvfiles(int);
|
||||
int ymrcvfiles(int, int);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
|
||||
#define MAX_BLOCK 8192
|
||||
#define sendline(c) PUTCHAR((c) & 0377)
|
||||
#define sendline(c) PUTCHAR((c & 0377))
|
||||
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
if (tmpf->remote) {
|
||||
bytes_sent = 0;
|
||||
@ -217,6 +224,7 @@ static int wctxpn(char *fname)
|
||||
if ((input_f != stdin) && *fname)
|
||||
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);
|
||||
// sprintf(p, "%lu %lo 0 0 0 0", (long) f.st_size, f.st_mtime);
|
||||
|
||||
Totalleft -= f.st_size;
|
||||
if (--Filesleft <= 0)
|
||||
@ -224,18 +232,9 @@ static int wctxpn(char *fname)
|
||||
if (Totalleft < 0)
|
||||
Totalleft = 0;
|
||||
|
||||
/* force 1k blocks if name won't fit in 128 byte block */
|
||||
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));
|
||||
purgeline(1);
|
||||
if (wcputsec(txbuf, 0, 128) == TERROR) {
|
||||
PUTSTR((char *)"wcputsec failed");
|
||||
Syslog('+', "%s/%s: wcputsec failed", fname,protname());
|
||||
Syslog('+', "%s: failed to send filename", protname());
|
||||
return TERROR;
|
||||
}
|
||||
return OK;
|
||||
@ -243,6 +242,9 @@ static int wctxpn(char *fname)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Get NAK, C or G
|
||||
*/
|
||||
static int getnak(void)
|
||||
{
|
||||
int firstch;
|
||||
@ -261,7 +263,7 @@ static int getnak(void)
|
||||
// return FALSE;
|
||||
case TIMEOUT:
|
||||
Syslog('x', "getnak: timeout try %d", tries);
|
||||
/* 50 seconds are enough */
|
||||
/* 50 seconds are enough (was 30, 26-11-2004 MB) */
|
||||
if (tries == 5) {
|
||||
Syslog('x', "Timeout on pathname");
|
||||
return TRUE;
|
||||
@ -283,16 +285,21 @@ static int getnak(void)
|
||||
io_mode(0, 2); /* Set cbreak, XON/XOFF, etc. */
|
||||
Optiong = TRUE;
|
||||
blklen=1024;
|
||||
Crcflg = TRUE;
|
||||
return FALSE;
|
||||
case WANTCRC:
|
||||
Syslog('x', "getnak: got WANTCRC");
|
||||
Crcflg = TRUE;
|
||||
return FALSE;
|
||||
case NAK:
|
||||
Syslog('x', "getnak: got NAK");
|
||||
return FALSE;
|
||||
case 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;
|
||||
}
|
||||
default:
|
||||
Syslog('x', "got %d", firstch);
|
||||
break;
|
||||
@ -316,7 +323,7 @@ static int wctx(long bytes_total)
|
||||
while ((firstch = GETCHAR(Rxtimeout)) != NAK && firstch != WANTCRC
|
||||
&& firstch != WANTG && firstch != TIMEOUT && firstch != CAN);
|
||||
if (firstch == CAN) {
|
||||
Syslog('x', "Receiver Cancelled");
|
||||
Syslog('+', "%s: receiver Cancelled during transfer", protname());
|
||||
return TERROR;
|
||||
}
|
||||
|
||||
@ -348,7 +355,6 @@ static int wctx(long bytes_total)
|
||||
do {
|
||||
purgeline(5);
|
||||
PUTCHAR(EOT);
|
||||
ioctl(1, TCFLSH, 0);
|
||||
++attempts;
|
||||
} while ((firstch = (GETCHAR(Rxtimeout)) != ACK) && 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");
|
||||
|
||||
for (attempts = 0; attempts <= RETRYMAX; attempts++) {
|
||||
Syslog('x', "send sector");
|
||||
Lastrx = firstch;
|
||||
sendline(cseclen == 1024 ? STX:SOH);
|
||||
sendline(sectnum);
|
||||
sendline(-sectnum -1);
|
||||
sendline((-sectnum -1));
|
||||
oldcrc = Checksum = 0;
|
||||
for (wcj = cseclen, cp = buf; --wcj >= 0; ) {
|
||||
sendline(*cp);
|
||||
@ -388,11 +393,10 @@ static int wcputsec(char *buf, int sectnum, size_t cseclen)
|
||||
oldcrc = updcrc16(0, updcrc16(0, oldcrc));
|
||||
sendline((int)oldcrc >> 8);
|
||||
sendline((int)oldcrc);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
sendline(Checksum);
|
||||
}
|
||||
|
||||
ioctl(1, TCFLSH, 0);
|
||||
if (Optiong) {
|
||||
firstsec = FALSE;
|
||||
return OK;
|
||||
@ -416,10 +420,9 @@ cancan:
|
||||
Crcflg = TRUE;
|
||||
case NAK:
|
||||
Syslog('+', "%s: got NAK on sector %d", protname(), sectnum);
|
||||
purgeline(10);
|
||||
purgeline(20);
|
||||
continue;
|
||||
case ACK:
|
||||
Syslog('x', "Got ACK");
|
||||
firstsec=FALSE;
|
||||
Totsecs += (cseclen>>7);
|
||||
return OK;
|
||||
|
@ -5,9 +5,9 @@
|
||||
|
||||
#define RETRYMAX 10
|
||||
|
||||
#define CPMEOF 032
|
||||
#define WANTCRC 0103 /* send C not NAK to get crc not checksum */
|
||||
#define WANTG 0107 /* Send G not NAK to get nonstop batch xmsn */
|
||||
#define CPMEOF 032 /* CP/M EOF, Ctrl-Z */
|
||||
#define WANTCRC 'C' /* send C not NAK to get crc not checksum */
|
||||
#define WANTG 'G' /* Send G not NAK to get nonstop batch xmsn */
|
||||
|
||||
|
||||
int ymsndfiles(down_list *, int);
|
||||
|
@ -80,7 +80,7 @@ extern int zmodem_requested;
|
||||
* This receiver will figure out what to do, you should
|
||||
* be able to send anything.
|
||||
*/
|
||||
int zmrcvfiles(int want1k)
|
||||
int zmrcvfiles(int want1k, int wantg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@ -99,7 +99,7 @@ int zmrcvfiles(int want1k)
|
||||
Syslog('+', "%s: switching to Ymodem", protname());
|
||||
protocol = ZM_YMODEM;
|
||||
}
|
||||
rc = ymrcvfiles(want1k);
|
||||
rc = ymrcvfiles(want1k, wantg);
|
||||
goto fubar;
|
||||
}
|
||||
|
||||
@ -128,8 +128,10 @@ fubar:
|
||||
io_mode(0, 1); /* Normal raw mode */
|
||||
/*
|
||||
* 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);
|
||||
return abs(rc);
|
||||
@ -151,7 +153,7 @@ int tryz(void)
|
||||
if (protocol != ZM_ZMODEM)
|
||||
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
|
||||
*/
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* $Id$ */
|
||||
|
||||
int procheader(char*);
|
||||
int zmrcvfiles(int);
|
||||
int zmrcvfiles(int, int);
|
||||
int putsec(char*,int);
|
||||
int closeit(int);
|
||||
|
||||
|
Reference in New Issue
Block a user