added internal zmodem download

This commit is contained in:
Michiel Broek 2004-11-08 14:36:34 +00:00
parent 5e3b1b09d5
commit c1ae6ed787
7 changed files with 432 additions and 459 deletions

View File

@ -32,6 +32,7 @@ v0.71.0 27-Oct-2004
from the users upload directory. from the users upload directory.
We don't reward upload time anymore, only bytes. It's more We don't reward upload time anymore, only bytes. It's more
troubles to implement right then it's worth these days. troubles to implement right then it's worth these days.
Added internal zmodem download protocol.
mbnewusr: mbnewusr:
Rewrote terminal i/o. Rewrote terminal i/o.

View File

@ -112,7 +112,7 @@ newuser.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h funcs.h inp
pinfo.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h pinfo.h input.h term.h ttyio.h pinfo.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h pinfo.h input.h term.h ttyio.h
timecheck.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h timecheck.h funcs.h bye.h exitinfo.h language.h input.h term.h ttyio.h timecheck.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h timecheck.h funcs.h bye.h exitinfo.h language.h input.h term.h ttyio.h
change.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h change.h dispfile.h funcs.h input.h language.h misc.h timeout.h exitinfo.h bye.h term.h ttyio.h change.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h change.h dispfile.h funcs.h input.h language.h misc.h timeout.h exitinfo.h bye.h term.h ttyio.h
transfer.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h transfer.h change.h whoson.h funcs.h term.h ttyio.h filesub.h language.h openport.h timeout.h transfer.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h transfer.h change.h whoson.h funcs.h term.h ttyio.h filesub.h language.h openport.h timeout.h zmsend.h
exitinfo.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h funcs.h input.h language.h oneline.h misc.h bye.h timeout.h timecheck.h exitinfo.h exitinfo.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h funcs.h input.h language.h oneline.h misc.h bye.h timeout.h timecheck.h exitinfo.h
mbsebbs.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h ../lib/msg.h mbsebbs.h user.h dispfile.h language.h menu.h misc.h bye.h timeout.h funcs.h term.h ttyio.h openport.h mbsebbs.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h ../lib/msg.h mbsebbs.h user.h dispfile.h language.h menu.h misc.h bye.h timeout.h funcs.h term.h ttyio.h openport.h
menu.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h oneline.h mail.h bbslist.h change.h chat.h file.h funcs.h input.h misc.h timeout.h menu.h page.h pinfo.h bye.h timecheck.h whoson.h language.h offline.h email.h door.h dispfile.h userlist.h timestats.h logentry.h morefile.h lastcallers.h signature.h term.h ttyio.h menu.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h oneline.h mail.h bbslist.h change.h chat.h file.h funcs.h input.h misc.h timeout.h menu.h page.h pinfo.h bye.h timecheck.h whoson.h language.h offline.h email.h door.h dispfile.h userlist.h timestats.h logentry.h morefile.h lastcallers.h signature.h term.h ttyio.h

View File

@ -318,6 +318,7 @@ void Download(void)
/* /*
* Download error * Download error
*/ */
Syslog('+', "Download error rc=%d", rc);
free(temp); free(temp);
tidy_download(&dl); tidy_download(&dl);
return; return;
@ -342,7 +343,7 @@ void Download(void)
PUTCHAR('.'); PUTCHAR('.');
if (Tag.Active) { if (Tag.Active) {
for (tmpf = dl; tmpf; tmpf = tmpf->next) { for (tmpf = dl; tmpf; tmpf = tmpf->next) {
if (strcmp(tmpf->remote, Tag.SFile) == 0) { if (strcmp(tmpf->remote, Tag.LFile) == 0) {
if (tmpf->sent) { if (tmpf->sent) {
Tag.Active = FALSE; Tag.Active = FALSE;

View File

@ -42,6 +42,7 @@
#include "language.h" #include "language.h"
#include "openport.h" #include "openport.h"
#include "timeout.h" #include "timeout.h"
#include "zmsend.h"
/* /*
@ -67,8 +68,8 @@
*/ */
int sentbytes = 0; int sentbytes;
int rcvdbytes = 0; int rcvdbytes;
@ -257,7 +258,14 @@ int download(down_list *download_list)
sleep(2); sleep(2);
if (uProtInternal) { if (uProtInternal) {
for (tmpf = download_list; tmpf && (maxrc < 2); tmpf = tmpf->next) { if (strncasecmp(sProtName, "zmodem", 6) == 0) {
sprintf(temp, "%s/%s/tag", CFG.bbs_usersdir, exitinfo.Name);
chdir(temp);
maxrc = zmsndfiles(download_list);
Home();
} else {
Syslog('!', "Warning internal protocol %s not supported", sProtName);
maxrc = 1;
} }
} else { } else {
gettimeofday(&starttime, &tz); gettimeofday(&starttime, &tz);
@ -347,6 +355,7 @@ int download(down_list *download_list)
tmpf->kfs ?"KFS":"KEEP", tmpf->sent ?"SENT":"N/A", tmpf->failed ?"FAILED":"N/A"); tmpf->kfs ?"KFS":"KEEP", tmpf->sent ?"SENT":"N/A", tmpf->failed ?"FAILED":"N/A");
} }
Syslog('b', "download() rc=%d", maxrc);
return maxrc; return maxrc;
} }

View File

@ -366,122 +366,112 @@ void zsda32(register char *buf, int length, int frameend)
*/ */
int zrdata(register char *buf, int length) int zrdata(register char *buf, int length)
{ {
register int c; register int c;
register unsigned short crc; register unsigned short crc;
register char *end; register char *end;
register int d; register int d;
switch (Crc32r) { switch (Crc32r) {
case 1: case 1:
return zrdat32(buf, length); return zrdat32(buf, length);
case 2: case 2:
return zrdatr32(buf, length); return zrdatr32(buf, length);
} }
crc = Rxcount = 0; end = buf + length; crc = Rxcount = 0; end = buf + length;
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: crc = updcrc16((((d=c))&0377), crc);
crc = updcrc16((((d=c))&0377), crc);
if ((c = zdlread()) & ~0377) if ((c = zdlread()) & ~0377)
goto crcfoo; goto crcfoo;
crc = updcrc16(c, crc); crc = updcrc16(c, crc);
if ((c = zdlread()) & ~0377) if ((c = zdlread()) & ~0377)
goto crcfoo; goto crcfoo;
crc = updcrc16(c, crc); crc = updcrc16(c, crc);
if (crc & 0xFFFF) { if (crc & 0xFFFF) {
Syslog('+', "Zmodem zrdata: Bad CRC"); Syslog('+', "Zmodem zrdata: Bad CRC");
return TERROR; return TERROR;
} }
Rxcount = length - (end - buf); Rxcount = length - (end - buf);
Syslog('z', "zrdata: %d %s", Rxcount, Zendnames[(d-GOTCRCE)&3]); Syslog('z', "zrdata: %d %s", Rxcount, 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 receiving data");
Syslog('+', "Zmodem: TIMEOUT receiving data");
return c; return c;
case HANGUP: case HANGUP: Syslog('+', "Zmodem: Carrier lost while receiving");
Syslog('+', "Zmodem: Carrier lost while receiving");
return c; return c;
default: default: garbitch();
garbitch();
return c; return c;
} }
}
*buf++ = c;
crc = updcrc16(c, crc);
} }
Syslog('+', "Zmodem: Data subpacket too long"); *buf++ = c;
return TERROR; crc = updcrc16(c, crc);
}
Syslog('+', "Zmodem: Data subpacket too long");
return TERROR;
} }
int zrdat32(register char *buf, int length) int zrdat32(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;
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 zrdat32: Bad CRC"); Syslog('+', "Zmodem zrdat32: Bad CRC");
return TERROR; return TERROR;
} }
Rxcount = length - (end - buf); Rxcount = length - (end - buf);
Syslog('z', "zrdat32: %d %s", Rxcount, Zendnames[(d-GOTCRCE)&3]); Syslog('z', "zrdat32: %d %s", Rxcount, 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;
case HANGUP: case HANGUP: Syslog('+', "Zmodem: Carrier lost while receiving");
Syslog('+', "Zmodem: Carrier lost while receiving");
return c; return c;
default: default: garbitch();
garbitch();
return c; return c;
} }
}
*buf++ = c;
crc = updcrc32(c, crc);
} }
Syslog('+', "Zmodem: Data subpacket too long"); *buf++ = c;
return TERROR; crc = updcrc32(c, crc);
}
Syslog('+', "Zmodem: Data subpacket too long");
return TERROR;
} }

View File

@ -36,7 +36,7 @@
#include "transfer.h" #include "transfer.h"
static int initsend(void); static int initsend(void);
static int sendzfile(char*,char*); static int sendzfile(char*);
static int finsend(void); static int finsend(void);
static int getzrxinit(void); static int getzrxinit(void);
@ -81,66 +81,71 @@ extern void free_frame_buffer(void);
int zmsndfiles(down_list *lst) int zmsndfiles(down_list *lst)
{ {
int rc, maxrc = 0; int rc, maxrc = 0;
down_list *tmpf; down_list *tmpf;
Syslog('+', "Zmodem: start Zmodem send"); Syslog('+', "Zmodem: start Zmodem send");
get_frame_buffer(); get_frame_buffer();
if ((rc = initsend())) {
if (txbuf)
free(txbuf);
txbuf = NULL;
free_frame_buffer();
return abs(rc);
}
for (tmpf = lst; tmpf && (maxrc < 2); tmpf = tmpf->next) {
if (tmpf->remote) {
rc = sendzfile(tmpf->local, tmpf->remote);
rc = abs(rc);
if (rc > maxrc)
maxrc = rc;
if (rc == 0)
unlink(tmpf->remote);
} else if (maxrc == 0)
unlink(tmpf->remote);
}
if (maxrc < 2) {
rc = finsend();
rc = abs(rc);
}
if (rc > maxrc)
maxrc = rc;
if ((rc = initsend())) {
if (txbuf) if (txbuf)
free(txbuf); free(txbuf);
txbuf = NULL; txbuf = NULL;
free_frame_buffer(); free_frame_buffer();
return abs(rc);
}
Syslog('z', "Zmodem: send rc=%d", maxrc); for (tmpf = lst; tmpf && (maxrc < 2); tmpf = tmpf->next) {
return (maxrc < 2)?0:maxrc; if (tmpf->remote) {
rc = sendzfile(tmpf->remote);
rc = abs(rc);
if (rc > maxrc)
maxrc = rc;
if (rc == 0) {
tmpf->sent = TRUE;
} else {
tmpf->failed = TRUE;
}
} else if (maxrc == 0) {
tmpf->failed = TRUE;
}
Syslog('z', "zmsndfiles: unlink(%s) returns %d", tmpf->remote, unlink(tmpf->remote));
}
if (maxrc < 2) {
rc = finsend();
rc = abs(rc);
}
if (rc > maxrc)
maxrc = rc;
if (txbuf)
free(txbuf);
txbuf = NULL;
free_frame_buffer();
Syslog('z', "Zmodem: send rc=%d", maxrc);
return (maxrc < 2)?0:maxrc;
} }
static int initsend(void) static int initsend(void)
{ {
Syslog('z', "Zmodem: initsend"); Syslog('z', "Zmodem: initsend");
PUTSTR((char *)"rz\r"); PUTSTR((char *)"rz\r");
stohdr(0x80L); /* Show we can do var header */ stohdr(0x80L); /* Show we can do var header */
zshhdr(4, ZRQINIT, Txhdr); zshhdr(4, ZRQINIT, Txhdr);
if (getzrxinit()) { if (getzrxinit()) {
Syslog('+', "Zmodem: Unable to initiate send"); Syslog('+', "Zmodem: Unable to initiate send");
return 1; return 1;
} }
return 0; return 0;
} }
@ -150,82 +155,76 @@ static int initsend(void)
*/ */
static int finsend(void) static int finsend(void)
{ {
int i, rc = 0; int i, rc = 0;
Syslog('z', "Zmodem: finsend"); Syslog('z', "Zmodem: finsend");
while (GETCHAR(1) >= 0) /*nothing*/; while (GETCHAR(1) >= 0) /*nothing*/;
for (i = 0; i < 30; i++) { for (i = 0; i < 30; i++) {
stohdr(0L); stohdr(0L);
zshhdr(4, ZFIN, Txhdr); zshhdr(4, ZFIN, Txhdr);
if ((rc = zgethdr(Rxhdr)) == ZFIN) if ((rc = zgethdr(Rxhdr)) == ZFIN)
PUTSTR((char *)"OO"); PUTSTR((char *)"OO");
if ((rc == ZFIN) || (rc == ZCAN) || (rc < 0)) if ((rc == ZFIN) || (rc == ZCAN) || (rc < 0))
break; break;
} }
return (rc != ZFIN); return (rc != ZFIN);
} }
static int sendzfile(char *ln, char *rn) static int sendzfile(char *rn)
{ {
int rc=0; int rc = 0;
struct stat st; struct stat st;
struct flock fl; struct flock fl;
int bufl; int bufl;
int sverr; int sverr;
fl.l_type = F_RDLCK; fl.l_type = F_RDLCK;
fl.l_whence = 0; fl.l_whence = 0;
fl.l_start = 0L; fl.l_start = 0L;
fl.l_len = 0L; fl.l_len = 0L;
if (txbuf == NULL) if (txbuf == NULL)
txbuf = malloc(MAXBLOCK); txbuf = malloc(MAXBLOCK);
skipsize = 0L; skipsize = 0L;
if ((in = fopen(ln, "r")) == NULL) { if ((in = fopen(rn, "r")) == NULL) {
sverr = errno; sverr = errno;
if ((sverr == ENOENT) || (sverr == EINVAL)) { if ((sverr == ENOENT) || (sverr == EINVAL)) {
Syslog('+', "File %s doesn't exist, removing", MBSE_SS(ln)); Syslog('+', "File %s doesn't exist, removing", MBSE_SS(rn));
return 0; return 0;
} else { } else {
WriteError("$Zmodem: cannot open file %s, skipping", MBSE_SS(ln)); WriteError("$Zmodem: cannot open file %s, skipping", MBSE_SS(rn));
return 1; return 1;
}
} }
}
if (fcntl(fileno(in),F_SETLK,&fl) != 0) { if (stat(rn,&st) != 0) {
Syslog('+', "$Zmodem: cannot lock file %s, skipping",MBSE_SS(ln)); Syslog('+', "$Zmodem: cannot access \"%s\", skipping",MBSE_SS(rn));
fclose(in); fclose(in);
return 1; return 1;
} }
if (stat(ln,&st) != 0) { Syslog('+', "Zmodem: send \"%s\"", MBSE_SS(rn));
Syslog('+', "$Zmodem: cannot access \"%s\", skipping",MBSE_SS(ln)); Syslog('+', "Zmodem: size %lu bytes, dated %s", (unsigned long)st.st_size, rfcdate(st.st_mtime));
fclose(in); gettimeofday(&starttime, &tz);
return 1;
}
Syslog('+', "Zmodem: send \"%s\" as \"%s\"", MBSE_SS(ln), MBSE_SS(rn)); sprintf(txbuf,"%s %lu %lo %o 0 0 0", rn,(unsigned long)st.st_size, st.st_mtime+(st.st_mtime%2), st.st_mode);
Syslog('+', "Zmodem: size %lu bytes, dated %s", (unsigned long)st.st_size, rfcdate(st.st_mtime)); bufl = strlen(txbuf);
gettimeofday(&starttime, &tz); *(strchr(txbuf,' ')) = '\0'; /*hope no blanks in filename*/
sprintf(txbuf,"%s %lu %lo %o 0 0 0", rn,(unsigned long)st.st_size, st.st_mtime+(st.st_mtime%2), st.st_mode); Eofseen = 0;
bufl = strlen(txbuf); rc = zsendfile(txbuf,bufl);
*(strchr(txbuf,' ')) = '\0'; /*hope no blanks in filename*/ if (rc == ZSKIP) {
Syslog('+', "Zmodem: remote skipped %s, is OK",MBSE_SS(rn));
Eofseen = 0; return 0;
rc = zsendfile(txbuf,bufl); } else if ((rc == OK) && (st.st_size - skipsize)) {
if (rc == ZSKIP) { gettimeofday(&endtime, &tz);
Syslog('+', "Zmodem: remote skipped %s, is OK",MBSE_SS(ln)); Syslog('+', "Zmodem: OK %s", transfertime(starttime, endtime, (unsigned long)st.st_size - skipsize, TRUE));
return 0; sentbytes += (unsigned long)st.st_size - skipsize;
} else if ((rc == OK) && (st.st_size - skipsize)) { return 0;
gettimeofday(&endtime, &tz); } else
Syslog('+', "Zmodem: OK %s", transfertime(starttime, endtime, (unsigned long)st.st_size - skipsize, TRUE)); return 2;
sentbytes += (unsigned long)st.st_size - skipsize;
return 0;
} else
return 2;
} }
@ -235,21 +234,21 @@ static int sendzfile(char *ln, char *rn)
*/ */
int getzrxinit(void) // CHECKED BUT NOT WELL TESTED int getzrxinit(void) // CHECKED BUT NOT WELL TESTED
{ {
int n; int n;
Syslog('z', "getzrxinit"); Syslog('z', "getzrxinit");
for (n=10; --n>=0; ) { for (n=10; --n>=0; ) {
switch (zgethdr(Rxhdr)) { switch (zgethdr(Rxhdr)) {
case ZCHALLENGE: /* Echo receiver's challenge numbr */ case ZCHALLENGE: /* Echo receiver's challenge numbr */
stohdr(Rxpos); stohdr(Rxpos);
zshhdr(4, ZACK, Txhdr); zshhdr(4, ZACK, Txhdr);
continue; continue;
case ZCOMMAND: /* They didn't see out ZRQINIT */ case ZCOMMAND: /* They didn't see out ZRQINIT */
stohdr(0L); stohdr(0L);
zshhdr(4, ZRQINIT, Txhdr); zshhdr(4, ZRQINIT, Txhdr);
continue; continue;
case ZRINIT: case ZRINIT:
Rxflags = 0377 & Rxhdr[ZF0]; Rxflags = 0377 & Rxhdr[ZF0];
Usevhdrs = Rxhdr[ZF1] & CANVHDR; Usevhdrs = Rxhdr[ZF1] & CANVHDR;
Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32)); Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
@ -276,20 +275,20 @@ int getzrxinit(void) // CHECKED BUT NOT WELL TESTED
Lztrans = 0; Lztrans = 0;
return (sendzsinit()); return (sendzsinit());
case ZCAN: case ZCAN:
case TIMEOUT: case TIMEOUT:
return TERROR; return TERROR;
case HANGUP: case HANGUP:
return HANGUP; return HANGUP;
case ZRQINIT: case ZRQINIT:
if (Rxhdr[ZF0] == ZCOMMAND) if (Rxhdr[ZF0] == ZCOMMAND)
continue; continue;
default: default:
zshhdr(4, ZNAK, Txhdr); zshhdr(4, ZNAK, Txhdr);
continue; continue;
}
} }
return TERROR; }
return TERROR;
} }
@ -299,33 +298,28 @@ int getzrxinit(void) // CHECKED BUT NOT WELL TESTED
*/ */
int sendzsinit(void) int sendzsinit(void)
{ {
int c; int c;
if (Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL))) if (Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL)))
return OK; return OK;
errors = 0; errors = 0;
for (;;) { for (;;) {
stohdr(0L); stohdr(0L);
if (Zctlesc) { if (Zctlesc) {
Txhdr[ZF0] |= TESCCTL; zshhdr(4, ZSINIT, Txhdr); Txhdr[ZF0] |= TESCCTL; zshhdr(4, ZSINIT, Txhdr);
} } else
else zsbhdr(4, ZSINIT, Txhdr);
zsbhdr(4, ZSINIT, Txhdr); zsdata(Myattn, ZATTNLEN, ZCRCW);
zsdata(Myattn, ZATTNLEN, ZCRCW); c = zgethdr(Rxhdr);
c = zgethdr(Rxhdr); switch (c) {
switch (c) { case ZCAN: return TERROR;
case ZCAN: case HANGUP: return HANGUP;
return TERROR; case ZACK: return OK;
case HANGUP: default: if (++errors > 19)
return HANGUP;
case ZACK:
return OK;
default:
if (++errors > 19)
return TERROR; return TERROR;
continue; continue;
}
} }
}
} }
@ -335,15 +329,15 @@ int sendzsinit(void)
*/ */
int zfilbuf(void) int zfilbuf(void)
{ {
int n; int n;
n = fread(txbuf, 1, blklen, in); n = fread(txbuf, 1, blklen, in);
if (n < blklen) { if (n < blklen) {
Eofseen = 1; Eofseen = 1;
Syslog('z', "zfilbuf return %d", n); Syslog('Z', "zfilbuf return %d", n);
} }
return n; return n;
} }
@ -353,42 +347,42 @@ int zfilbuf(void)
*/ */
int zsendfile(char *buf, int blen) int zsendfile(char *buf, int blen)
{ {
int c; int c;
register unsigned long crc = -1; register unsigned long crc = -1;
long lastcrcrq = -1; long lastcrcrq = -1;
Syslog('z', "zsendfile %s (%d)", buf, blen); Syslog('z', "zsendfile %s (%d)", buf, blen);
for (errors=0; ++errors<11;) { for (errors=0; ++errors<11;) {
Txhdr[ZF0] = Lzconv; /* file conversion request */ Txhdr[ZF0] = Lzconv; /* file conversion request */
Txhdr[ZF1] = Lzmanag; /* file management request */ Txhdr[ZF1] = Lzmanag; /* file management request */
if (Lskipnocor) if (Lskipnocor)
Txhdr[ZF1] |= ZMSKNOLOC; Txhdr[ZF1] |= ZMSKNOLOC;
Txhdr[ZF2] = Lztrans; /* file transport request */ Txhdr[ZF2] = Lztrans; /* file transport request */
Txhdr[ZF3] = 0; Txhdr[ZF3] = 0;
zsbhdr(4, ZFILE, Txhdr); zsbhdr(4, ZFILE, Txhdr);
zsdata(buf, blen, ZCRCW); zsdata(buf, blen, ZCRCW);
again: again:
c = zgethdr(Rxhdr); c = zgethdr(Rxhdr);
switch (c) { switch (c) {
case ZRINIT: case ZRINIT:
while ((c = GETCHAR(5)) > 0) while ((c = GETCHAR(5)) > 0)
if (c == ZPAD) { if (c == ZPAD) {
goto again; goto again;
} }
continue; continue;
case ZCAN: case ZCAN:
case TIMEOUT: case TIMEOUT:
case ZABORT: case ZABORT:
case ZFIN: case ZFIN:
Syslog('+', "Zmodem: Got %s on pathname", frametypes[c+FTOFFSET]); Syslog('+', "Zmodem: Got %s on pathname", frametypes[c+FTOFFSET]);
return TERROR; return TERROR;
default: default:
Syslog('+', "Zmodem: Got %d frame type on pathname", c); Syslog('+', "Zmodem: Got %d frame type on pathname", c);
continue; continue;
case TERROR: case TERROR:
case ZNAK: case ZNAK:
continue; continue;
case ZCRC: case ZCRC:
if (Rxpos != lastcrcrq) { if (Rxpos != lastcrcrq) {
lastcrcrq = Rxpos; lastcrcrq = Rxpos;
crc = 0xFFFFFFFFL; crc = 0xFFFFFFFFL;
@ -402,11 +396,11 @@ again:
stohdr(crc); stohdr(crc);
zsbhdr(4, ZCRC, Txhdr); zsbhdr(4, ZCRC, Txhdr);
goto again; goto again;
case ZFERR: case ZFERR:
case ZSKIP: case ZSKIP:
Syslog('+', "Zmodem: File skipped by receiver request"); Syslog('+', "Zmodem: File skipped by receiver request");
fclose(in); return c; fclose(in); return c;
case ZRPOS: case ZRPOS:
/* /*
* Suppress zcrcw request otherwise triggered by * Suppress zcrcw request otherwise triggered by
* lastyunc==bytcnt * lastyunc==bytcnt
@ -417,9 +411,9 @@ again:
return TERROR; return TERROR;
Lastsync = (bytcnt = Txpos = Lrxpos = Rxpos) -1; Lastsync = (bytcnt = Txpos = Lrxpos = Rxpos) -1;
return zsendfdata(); return zsendfdata();
}
} }
fclose(in); return TERROR; }
fclose(in); return TERROR;
} }
@ -429,171 +423,155 @@ again:
*/ */
int zsendfdata(void) int zsendfdata(void)
{ {
int c=0, e, n; int c = 0, e, n;
int newcnt; int newcnt;
int tcount = 0; int tcount = 0;
int junkcount; /* Counts garbage chars received by TX */ int junkcount; /* Counts garbage chars received by TX */
int maxblklen, goodblks = 0, goodneeded = 8; int maxblklen, goodblks = 0, goodneeded = 8;
maxblklen = 1024; // FIXME: 8K variant set this to 8K maxblklen = 1024; // FIXME: 8K variant set this to 8K
Syslog('z', "zsendfdata() maxblklen=%d", maxblklen); Syslog('z', "zsendfdata() maxblklen=%d", maxblklen);
junkcount = 0; junkcount = 0;
Beenhereb4 = 0; Beenhereb4 = 0;
somemore: somemore:
if (0) { if (0) {
waitack: waitack:
junkcount = 0; junkcount = 0;
c = getinsync(0); c = getinsync(0);
gotack: gotack:
switch (c) { switch (c) {
default: default:
case ZCAN: case ZCAN: fclose(in);
fclose(in); return TERROR;
return TERROR; case ZRINIT: fclose(in);
case ZRINIT: return ZSKIP;
fclose(in); case ZSKIP: fclose(in);
return ZSKIP; return c;
case ZSKIP: case ZACK: break; // Possible bug, added 23-08-99
fclose(in); case ZRPOS: blklen = ((blklen >> 2) > 64) ? (blklen >> 2) : 64;
return c; goodblks = 0;
case ZACK: goodneeded = ((goodneeded << 1) > 16) ? 16 : goodneeded << 1;
break; // Possible bug, added 23-08-99 Syslog('z', "zmsend: blocklen now %d", blklen);
case ZRPOS: break;
blklen = ((blklen >> 2) > 64) ? (blklen >> 2) : 64; case TIMEOUT: /* Put back here 08-09-1999 mb */
goodblks = 0; Syslog('z', "zmsend: zsendfdata TIMEOUT");
goodneeded = ((goodneeded << 1) > 16) ? 16 : goodneeded << 1; goto to;
Syslog('z', "zmsend: blocklen now %d", blklen); case HANGUP: /* New, added 08-09-1999 mb */
break; Syslog('z', "zmsend: zsendfdata HANGUP");
case TIMEOUT: /* Put back here 08-09-1999 mb */ fclose(in);
Syslog('z', "zmsend: zsendfdata TIMEOUT"); return c;
goto to;
case HANGUP: /* New, added 08-09-1999 mb */
Syslog('z', "zmsend: zsendfdata HANGUP");
fclose(in);
return c;
}
/*
* If the reverse channel can be tested for data,
* this logic may be used to detect error packets
* sent by the receiver, in place of setjmp/longjmp
* rdchk(fd) returns non 0 if a character is available
*/
if (TCHECK()) {
c = GETCHAR(1);
Syslog('z', "zsendfdata(): check getchar(1)=%d", c);
if (c < 0) {
return c;
} else switch (c) {
case CAN:
case ZPAD:
c = getinsync(1);
goto gotack;
case XOFF: /* Wait a while for an XON */
case XOFF|0200:
GETCHAR(10);
}
}
} }
/*
* If the reverse channel can be tested for data,
* this logic may be used to detect error packets
* sent by the receiver, in place of setjmp/longjmp
* rdchk(fd) returns non 0 if a character is available
*/
if (TCHECK()) {
c = GETCHAR(1);
Syslog('z', "zsendfdata(): check getchar(1)=%d", c);
if (c < 0) {
return c;
} else switch (c) {
case CAN:
case ZPAD: c = getinsync(1);
goto gotack;
case XOFF: /* Wait a while for an XON */
case XOFF|0200: GETCHAR(10);
}
}
}
to: to:
newcnt = Rxbuflen; newcnt = Rxbuflen;
Txwcnt = 0; Txwcnt = 0;
stohdr(Txpos); stohdr(Txpos);
zsbhdr(4, ZDATA, Txhdr); zsbhdr(4, ZDATA, Txhdr);
do { do {
n = zfilbuf(); n = zfilbuf();
if (Eofseen) if (Eofseen)
e = ZCRCE; e = ZCRCE;
else if (junkcount > 3) else if (junkcount > 3)
e = ZCRCW; e = ZCRCW;
else if (bytcnt == Lastsync) else if (bytcnt == Lastsync)
e = ZCRCW; e = ZCRCW;
else if (Rxbuflen && (newcnt -= n) <= 0) else if (Rxbuflen && (newcnt -= n) <= 0)
e = ZCRCW; e = ZCRCW;
else if (Txwindow && (Txwcnt += n) >= Txwspac) { else if (Txwindow && (Txwcnt += n) >= Txwspac) {
Txwcnt = 0; e = ZCRCQ; Txwcnt = 0; e = ZCRCQ;
} else } else
e = ZCRCG; e = ZCRCG;
Syslog('z', "%7ld ZMODEM%s ", Syslog('Z', "%7ld ZMODEM%s ", Txpos, Crc32t?" CRC-32":"");
Txpos, Crc32t?" CRC-32":""); Nopper();
Nopper(); zsdata(txbuf, n, e);
zsdata(txbuf, n, e); bytcnt = Txpos += n;
bytcnt = Txpos += n;
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;
/* /*
* If the reverse channel can be tested for data, * If the reverse channel can be tested for data,
* this logic may be used to detect error packets * this logic may be used to detect error packets
* sent by the receiver, in place of setjmp/longjmp * sent by the receiver, in place of setjmp/longjmp
* rdchk(fd) returns non 0 if a character is available * rdchk(fd) returns non 0 if a character is available
*/ */
if (TCHECK()) { if (TCHECK()) {
c = GETCHAR(1); c = GETCHAR(1);
if (c < 0) { if (c < 0) {
return c; return c;
} else switch (c) { } else switch (c) {
case CAN: case CAN:
case ZPAD: case ZPAD: c = getinsync(1);
c = getinsync(1);
if (c == ZACK) if (c == ZACK)
break; break;
/* zcrce - dinna wanna starta ping-pong game */ /* zcrce - dinna wanna starta ping-pong game */
zsdata(txbuf, 0, ZCRCE); zsdata(txbuf, 0, ZCRCE);
goto gotack; goto gotack;
case XOFF: /* Wait a while for an XON */ case XOFF: /* Wait a while for an XON */
case XOFF|0200: case XOFF|0200: GETCHAR(10);
GETCHAR(10); default: ++junkcount;
default: }
++junkcount;
}
}
if (Txwindow) {
while ((tcount = (Txpos - Lrxpos)) >= Txwindow) {
Syslog('z', "%ld window >= %u", tcount, Txwindow);
if (e != ZCRCQ)
zsdata(txbuf, 0, e = ZCRCQ);
c = getinsync(1);
if (c != ZACK) {
zsdata(txbuf, 0, ZCRCE);
goto gotack;
}
}
Syslog('z', "window = %ld", tcount);
}
} while (!Eofseen);
for (;;) {
stohdr(Txpos);
zsbhdr(4, ZEOF, Txhdr);
egotack:
switch (getinsync(0)) {
case ZACK:
Syslog('z', "zsendfdata() ZACK");
goto egotack; // continue in old source
case ZRPOS:
goto somemore;
case ZRINIT:
fclose(in);
return OK;
case ZSKIP:
fclose(in);
Syslog('+', "Zmodem: File skipped by receiver request");
return ZSKIP;
default:
Syslog('+', "Zmodem: Got %d trying to send end of file", c);
case TERROR:
fclose(in);
return TERROR;
}
} }
if (Txwindow) {
while ((tcount = (Txpos - Lrxpos)) >= Txwindow) {
Syslog('z', "%ld window >= %u", tcount, Txwindow);
if (e != ZCRCQ)
zsdata(txbuf, 0, e = ZCRCQ);
c = getinsync(1);
if (c != ZACK) {
zsdata(txbuf, 0, ZCRCE);
goto gotack;
}
}
Syslog('z', "window = %ld", tcount);
}
} while (!Eofseen);
for (;;) {
stohdr(Txpos);
zsbhdr(4, ZEOF, Txhdr);
egotack:
switch (getinsync(0)) {
case ZACK: Syslog('z', "zsendfdata() ZACK");
goto egotack; // continue in old source
case ZRPOS: goto somemore;
case ZRINIT: fclose(in);
return OK;
case ZSKIP: fclose(in);
Syslog('+', "Zmodem: File skipped by receiver request");
return ZSKIP;
default: Syslog('+', "Zmodem: Got %d trying to send end of file", c);
case TERROR: fclose(in);
return TERROR;
}
}
} }
@ -603,64 +581,58 @@ egotack:
*/ */
int getinsync(int flag) int getinsync(int flag)
{ {
int c = 0; int c = 0;
Syslog('z', "getinsync(%d)", flag); Syslog('z', "getinsync(%d)", flag);
for (;;) { for (;;) {
c = zgethdr(Rxhdr); c = zgethdr(Rxhdr);
switch (c) { switch (c) {
case HANGUP: case HANGUP: return HANGUP;
return HANGUP; 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: return TERROR;
Syslog('+', "Zmodem: Got %s sending data", frametypes[c+FTOFFSET]); case ZRPOS: /* ************************************* */
return TERROR; /* If sending to a buffered modem, you */
case ZRPOS: /* might send a break at this point to */
/* ************************************* */ /* dump the modem's buffer. */
/* If sending to a buffered modem, you */ clearerr(in); /* In case file EOF seen */
/* might send a break at this point to */ if (fseek(in, Rxpos, 0)) {
/* dump the modem's buffer. */
clearerr(in); /* In case file EOF seen */
if (fseek(in, Rxpos, 0)) {
Syslog('+', "Zmodem: Bad Seek to %ld", Rxpos); Syslog('+', "Zmodem: Bad Seek to %ld", Rxpos);
return TERROR; return TERROR;
} }
Eofseen = 0; Eofseen = 0;
bytcnt = Lrxpos = Txpos = Rxpos; bytcnt = Lrxpos = Txpos = Rxpos;
if (Lastsync == Rxpos) { if (Lastsync == Rxpos) {
if (++Beenhereb4 > 12) { if (++Beenhereb4 > 12) {
Syslog('+', "Zmodem: Can't send block"); Syslog('+', "Zmodem: Can't send block");
return TERROR; return TERROR;
} }
if (Beenhereb4 > 4) if (Beenhereb4 > 4) {
if (blklen > 32) { if (blklen > 32) {
blklen /= 2; blklen /= 2;
Syslog('z', "Zmodem: blocklen now %d", blklen); Syslog('z', "Zmodem: blocklen now %d", blklen);
} }
} }
else } else {
Beenhereb4=0; Beenhereb4=0;
Lastsync = Rxpos; }
return c; Lastsync = Rxpos;
case ZACK: return c;
Lrxpos = Rxpos; case ZACK: Lrxpos = Rxpos;
if (flag || Txpos == Rxpos) if (flag || Txpos == Rxpos)
return ZACK; return ZACK;
continue; continue;
case ZRINIT: case ZRINIT: return c;
return c; case ZSKIP: Syslog('+', "Zmodem: File skipped by receiver request");
case ZSKIP: return c;
Syslog('+', "Zmodem: File skipped by receiver request"); default: zsbhdr(4, ZNAK, Txhdr);
return c; continue;
default:
zsbhdr(4, ZNAK, Txhdr);
continue;
}
} }
}
} }
@ -671,14 +643,14 @@ int getinsync(int flag)
*/ */
void initzsendmsk(register char *p) void initzsendmsk(register char *p)
{ {
int c; int c;
for (c = 0; c < 33; ++c) { for (c = 0; c < 33; ++c) {
if (p[c>>3] & (1 << (c & 7))) { if (p[c>>3] & (1 << (c & 7))) {
Zsendmask[c] = 1; Zsendmask[c] = 1;
Syslog('z', "Zmodem: Escaping %02o", c); Syslog('z', "Zmodem: Escaping %02o", c);
}
} }
}
} }

View File

@ -4,7 +4,7 @@
/* $Id$ */ /* $Id$ */
int zmsndfiles(down_list *lst) int zmsndfiles(down_list *);
#endif #endif