Added xmodem and ymodem download

This commit is contained in:
Michiel Broek 2004-11-22 22:05:57 +00:00
parent 3b5d10b78e
commit eb47392373
8 changed files with 220 additions and 124 deletions

View File

@ -46,6 +46,14 @@ v0.71.0 27-Oct-2004
With user chat, the timeout timer wasn't refreshed. With user chat, the timeout timer wasn't refreshed.
Rewrote the rewritten terminal i/o to get zmodem upload to Rewrote the rewritten terminal i/o to get zmodem upload to
work. work.
Added ymodem and xmodem download protocols, both with option
for 1k blocks. Not yet enabled for public use also.
Note: you could enable the internal protocols by adding these
to the protocol setup. But I recommend against it because not
yet all safety checks for uploads are installed. When the time
is right I will change mbsetup so that these protocols will be
automatic added.
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 zmsend.h zmrecv.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 zmmisc.h zmsend.h zmrecv.h ymsend.h ymrecv.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
@ -132,9 +132,9 @@ dispfile.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h ../lib/msg
userlist.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h userlist.h language.h input.h timeout.h term.h ttyio.h userlist.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h userlist.h language.h input.h timeout.h term.h ttyio.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 ymsend.h ttyio.h zmmisc.h transfer.h openport.h timeout.h term.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 ymrecv.h ymrecv.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ymrecv.h
zmmisc.o: ../config.h ../lib/mbselib.h ttyio.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 openport.h timeout.h input.h zmrecv.o: ../config.h ../lib/mbselib.h ../lib/users.h ttyio.h transfer.h zmmisc.h zmrecv.h openport.h timeout.h input.h
# End of generated dependencies # End of generated dependencies

View File

@ -42,8 +42,11 @@
#include "language.h" #include "language.h"
#include "openport.h" #include "openport.h"
#include "timeout.h" #include "timeout.h"
#include "zmmisc.h"
#include "zmsend.h" #include "zmsend.h"
#include "zmrecv.h" #include "zmrecv.h"
#include "ymsend.h"
#include "ymrecv.h"
/* /*
@ -259,16 +262,24 @@ int download(down_list *download_list)
sleep(2); sleep(2);
if (uProtInternal) { if (uProtInternal) {
sprintf(temp, "%s/%s/tag", CFG.bbs_usersdir, exitinfo.Name);
chdir(temp);
if (strncasecmp(sProtName, "zmodem 8k", 9) == 0) { if (strncasecmp(sProtName, "zmodem 8k", 9) == 0) {
sprintf(temp, "%s/%s/tag", CFG.bbs_usersdir, exitinfo.Name);
chdir(temp);
maxrc = zmsndfiles(download_list, TRUE); maxrc = zmsndfiles(download_list, TRUE);
Home(); Home();
} else if (strncasecmp(sProtName, "zmodem", 6) == 0) { } else if (strncasecmp(sProtName, "zmodem", 6) == 0) {
sprintf(temp, "%s/%s/tag", CFG.bbs_usersdir, exitinfo.Name);
chdir(temp);
maxrc = zmsndfiles(download_list, FALSE); maxrc = zmsndfiles(download_list, FALSE);
Home(); Home();
} else if ((strncasecmp(sProtName, "xmodem", 6) == 0) || (strncasecmp(sProtName, "ymodem", 6) == 0)) {
if (strncasecmp(sProtName, "xmodem", 6) == 0)
protocol = ZM_XMODEM;
else
protocol = ZM_YMODEM;
if (strstr(sProtName, "1K") || strstr(sProtName, "1k"))
maxrc = ymsndfiles(download_list, TRUE);
else
maxrc = ymsndfiles(download_list, FALSE);
Home();
} else { } else {
Syslog('!', "Warning internal protocol %s not supported", sProtName); Syslog('!', "Warning internal protocol %s not supported", sProtName);
maxrc = 1; maxrc = 1;

View File

@ -31,45 +31,124 @@
#include "../config.h" #include "../config.h"
#include "../lib/mbselib.h" #include "../lib/mbselib.h"
#include "../lib/mbse.h" #include "../lib/mbse.h"
#include "ymsend.h"
#include "ttyio.h" #include "ttyio.h"
#include "zmmisc.h" #include "zmmisc.h"
#include "transfer.h" #include "transfer.h"
#include "openport.h" #include "openport.h"
#include "timeout.h" #include "timeout.h"
#include "term.h" #include "term.h"
#include "ymsend.h"
#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;
char Crcflg; char Crcflg;
char Lastrx; char Lastrx;
int Fullname=0; /* transmit full pathname */ int Fullname = 0; /* transmit full pathname */
int Filesleft; int Filesleft;
long Totalleft; long Totalleft;
long bytes_sent; long bytes_sent;
int Ascii=0; /* Add CR's for brain damaged programs */ int firstsec;
int firstsec; int Optiong; /* Let it rip no wait for sector ACK's */
int Optiong; /* Let it rip no wait for sector ACK's */ int Totsecs; /* total number of sectors this file */
int Lfseen=0; char *txbuf;
int Totsecs; /* total number of sectors this file */ size_t blklen = 128; /* length of transmitted records */
char *txbuf; int zmodem_requested = 0;
size_t blklen=128; /* length of transmitted records */ static int no_unixmode;
int zmodem_requested = 0; struct timeval starttime, endtime;
int Dottoslash=0; /* Change foo.bar.baz to foo/bar/baz */ struct timezone tz;
static int no_unixmode; long skipsize;
extern int Rxtimeout; extern int Rxtimeout;
static int wctxpn(char *);
static int getnak(void); static int getnak(void);
int wcputsec(char *, int, size_t); static int wctx(long);
static int wcputsec(char *, int, size_t);
static size_t filbuf(char *, size_t); static size_t filbuf(char *, size_t);
int ymsndfiles(down_list *lst, int use1k)
{
int maxrc = 0;
down_list *tmpf;
Syslog('+', "%s: start send files", protname());
txbuf = malloc(MAX_BLOCK);
/*
* Count files to transmit
*/
Totalleft = Filesleft = 0;
for (tmpf = lst; tmpf; tmpf = tmpf->next) {
if (tmpf->remote) {
Filesleft++;
Totalleft += tmpf->size;
}
}
Syslog('x', "%s: %d files, size %d bytes", protname(), Filesleft, Totalleft);
for (tmpf = lst; tmpf && (maxrc < 2); tmpf = tmpf->next) {
if (tmpf->remote) {
bytes_sent = 0;
skipsize = 0L;
Totsecs = 0;
switch (wctxpn(tmpf->remote)) {
case TERROR: Syslog('x', "wctxpn returns error");
tmpf->failed = TRUE;
maxrc = 2;
break;
case ZSKIP: Syslog('x', "wctxpn returns skip");
tmpf->failed = TRUE;
break;
case OK: gettimeofday(&starttime, &tz);
if ((blklen == 128) && use1k) {
Syslog('x', "%s: will use 1K blocks", protname());
blklen = 1024;
}
if (wctx(tmpf->size) == ERROR) {
Syslog('x', "wctx returned error");
tmpf->failed = TRUE;
} else {
tmpf->sent = TRUE;
gettimeofday(&endtime, &tz);
Syslog('+', "%s: OK %s", protname(),
transfertime(starttime, endtime, (unsigned long)tmpf->size - skipsize, TRUE));
}
}
} else if (maxrc == 0) {
tmpf->failed = TRUE;
}
if (unlink(tmpf->remote))
Syslog('+', "%s: could not unlink %s", protname(), tmpf->remote);
}
if (protocol == ZM_YMODEM) {
/*
* Send empty filename to signal end of batch
*/
wctxpn((char *)"");
}
if (txbuf)
free(txbuf);
txbuf = NULL;
io_mode(0, 1);
Syslog('x', "%s: send rc=%d", protname(), maxrc);
return (maxrc < 2)?0:maxrc;
}
/* /*
* generate and transmit pathname block consisting of * generate and transmit pathname block consisting of
* pathname (null terminated), * pathname (null terminated),
@ -84,39 +163,40 @@ static int wctxpn(char *fname)
struct stat f; struct stat f;
name2 = alloca(PATH_MAX+1); name2 = alloca(PATH_MAX+1);
input_f = fopen(fname, "r");
if (protocol == ZM_XMODEM) { if ((input_f = fopen(fname, "r"))) {
if (*fname && fstat(fileno(input_f), &f) != -1) { fstat(fileno(input_f), &f);
Syslog('y', "Sending %s, %ld blocks: ", fname, (long) (f.st_size >> 7));
Syslog('+', "%s: send \"%s\"", protname(), MBSE_SS(fname));
Syslog('+', "%s: size %lu bytes, dated %s", protname(), (unsigned long)f.st_size, rfcdate(f.st_mtime));
if (protocol == ZM_XMODEM) {
if (*fname) {
sprintf(name2, "Sending %s, %ld blocks: ", fname, (long) (f.st_size >> 7));
PUTSTR(name2);
Enter(1);
}
PUTSTR((char *)"Give your local XMODEM receive command now.");
Enter(1);
return OK;
} }
PUTSTR((char *)"Give your local XMODEM receive command now."); } else {
Enter(1); /*
return OK; * Reset, this normally happens for the ymodem end of batch block.
*/
f.st_size = 0;
f.st_mtime = 0;
f.st_mode = 0;
} }
if (!zmodem_requested) // if (!zmodem_requested)
if (getnak()) { if (getnak()) {
PUTSTR((char *)"getnak failed"); PUTSTR((char *)"getnak failed");
Syslog('+', "%s/%s: getnak failed", fname, protname()); Syslog('+', "%s/%s: getnak failed", MBSE_SS(fname), protname());
return ERROR; return TERROR;
} }
q = (char *) 0; q = (char *) 0;
if (Dottoslash) { /* change . to . */
for (p = fname; *p; ++p) {
if (*p == '/')
q = p;
else if (*p == '.')
*(q=p) = '/';
}
if (q && strlen(++q) > 8) { /* If name>8 chars */
q += 8; /* make it .ext */
strcpy(name2, q); /* save excess of name */
*q = '.';
strcpy(++q, name2); /* add it back */
}
}
for (p = fname, q = txbuf ; *p; ) for (p = fname, q = txbuf ; *p; )
if ((*q++ = *p++) == '/' && !Fullname) if ((*q++ = *p++) == '/' && !Fullname)
@ -125,21 +205,24 @@ static int wctxpn(char *fname)
p = q; p = q;
while (q < (txbuf + MAX_BLOCK)) while (q < (txbuf + MAX_BLOCK))
*q++ = 0; *q++ = 0;
/* /*
* note that we may lose some information here in case mode_t is wider than an * note that we may lose some information here in case mode_t is wider than an
* int. But i believe sending %lo instead of %o _could_ break compatability * int. But i believe sending %lo instead of %o _could_ break compatability
*/ */
if (!Ascii && (input_f != stdin) && *fname && fstat(fileno(input_f), &f)!= -1) 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);
// if (Verbose) Syslog('x', "Sending: %s", txbuf);
// vstringf(_("Sending: %s\n"),txbuf);
Totalleft -= f.st_size; Totalleft -= f.st_size;
if (--Filesleft <= 0) if (--Filesleft <= 0)
Totalleft = 0; Totalleft = 0;
if (Totalleft < 0) if (Totalleft < 0)
Totalleft = 0; Totalleft = 0;
Syslog('x', "Totalleft = %d", Totalleft);
/* force 1k blocks if name won't fit in 128 byte block */ /* force 1k blocks if name won't fit in 128 byte block */
if (txbuf[125]) if (txbuf[125])
blklen=1024; blklen=1024;
@ -152,7 +235,7 @@ static int wctxpn(char *fname)
if (wcputsec(txbuf, 0, 128)==ERROR) { if (wcputsec(txbuf, 0, 128)==ERROR) {
PUTSTR((char *)"wcputsec failed"); PUTSTR((char *)"wcputsec failed");
Syslog('+', "%s/%s: wcputsec failed", fname,protname()); Syslog('+', "%s/%s: wcputsec failed", fname,protname());
return ERROR; return TERROR;
} }
return OK; return OK;
} }
@ -164,7 +247,9 @@ static int getnak(void)
int firstch; int firstch;
int tries = 0; int tries = 0;
Syslog('x', "getnak()");
Lastrx = 0; Lastrx = 0;
for (;;) { for (;;) {
tries++; tries++;
switch (firstch = GETCHAR(10)) { switch (firstch = GETCHAR(10)) {
@ -174,9 +259,10 @@ static int getnak(void)
// Ascii = 0; /* Receiver does the conversion */ // Ascii = 0; /* Receiver does the conversion */
// return FALSE; // return FALSE;
case TIMEOUT: case TIMEOUT:
Syslog('x', "getnak: timeout try %d", tries);
/* 30 seconds are enough */ /* 30 seconds are enough */
if (tries == 3) { if (tries == 3) {
Syslog('y', "Timeout on pathname"); Syslog('x', "Timeout on pathname");
return TRUE; return TRUE;
} }
/* don't send a second ZRQINIT _directly_ after the /* don't send a second ZRQINIT _directly_ after the
@ -192,14 +278,18 @@ static int getnak(void)
// } // }
continue; continue;
case WANTG: case WANTG:
Syslog('x', "getnak: got WANTG");
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;
case WANTCRC: case WANTCRC:
Syslog('x', "getnak: got WANTCRC");
Crcflg = TRUE; Crcflg = TRUE;
case NAK: case NAK:
Syslog('x', "getnak: got NAK");
return FALSE; return FALSE;
case CAN: case CAN:
Syslog('x', "getnak: got CAN");
if ((firstch = GETCHAR(2)) == CAN && Lastrx == CAN) if ((firstch = GETCHAR(2)) == CAN && Lastrx == CAN)
return TRUE; return TRUE;
default: default:
@ -207,6 +297,7 @@ static int getnak(void)
} }
Lastrx = firstch; Lastrx = firstch;
} }
Syslog('x', "getnak: done");
} }
@ -217,13 +308,13 @@ static int wctx(long bytes_total)
register int sectnum, attempts, firstch; register int sectnum, attempts, firstch;
firstsec=TRUE; thisblklen = blklen; firstsec=TRUE; thisblklen = blklen;
Syslog('y', "wctx:file length=%ld", bytes_total); Syslog('x', "wctx: file length=%ld, blklen=%d", bytes_total, blklen);
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('y', "Receiver Cancelled"); Syslog('x', "Receiver Cancelled");
return ERROR; return TERROR;
} }
if (firstch == WANTCRC) if (firstch == WANTCRC)
@ -238,7 +329,7 @@ static int wctx(long bytes_total)
if ( !filbuf(txbuf, thisblklen)) if ( !filbuf(txbuf, thisblklen))
break; break;
if (wcputsec(txbuf, ++sectnum, thisblklen) == TERROR) if (wcputsec(txbuf, ++sectnum, thisblklen) == TERROR)
return ERROR; return TERROR;
bytes_sent += thisblklen; bytes_sent += thisblklen;
} }
@ -246,21 +337,21 @@ static int wctx(long bytes_total)
attempts = 0; attempts = 0;
do { do {
// purgeline(io_mode_fd); purgeline(5);
PUTCHAR(EOT); PUTCHAR(EOT);
fflush(stdout); fflush(stdout);
++attempts; ++attempts;
} while ((firstch = (GETCHAR(Rxtimeout)) != ACK) && attempts < RETRYMAX); } while ((firstch = (GETCHAR(Rxtimeout)) != ACK) && attempts < RETRYMAX);
if (attempts == RETRYMAX) { if (attempts == RETRYMAX) {
Syslog('y', "No ACK on EOT"); Syslog('x', "No ACK on EOT");
return ERROR; return TERROR;
} else } else
return OK; return OK;
} }
int wcputsec(char *buf, int sectnum, size_t cseclen) static int wcputsec(char *buf, int sectnum, size_t cseclen)
{ {
int Checksum, wcj; int Checksum, wcj;
char *cp; char *cp;
@ -269,8 +360,9 @@ int wcputsec(char *buf, int sectnum, size_t cseclen)
int attempts; int attempts;
firstch = 0; /* part of logic to detect CAN CAN */ firstch = 0; /* part of logic to detect CAN CAN */
Syslog('y', "%s sectors/kbytes sent: %3d/%2dk", protname(), Totsecs, Totsecs/8 ); Syslog('x', "wcputsec: sectnum %d, len %d", sectnum, cseclen);
Syslog('x', "%s sectors/kbytes sent: %3d/%2dk", protname(), Totsecs, Totsecs/8 );
for (attempts = 0; attempts <= RETRYMAX; attempts++) { for (attempts = 0; attempts <= RETRYMAX; attempts++) {
Lastrx = firstch; Lastrx = firstch;
@ -300,30 +392,31 @@ int wcputsec(char *buf, int sectnum, size_t cseclen)
gotnak: gotnak:
switch (firstch) { switch (firstch) {
case CAN: case CAN:
Syslog('x', "got CAN");
if(Lastrx == CAN) { if(Lastrx == CAN) {
cancan: cancan:
Syslog('y', "Cancelled"); Syslog('x', "Cancelled");
return ERROR; return ERROR;
} }
break; break;
case TIMEOUT: case TIMEOUT:
Syslog('y', "Timeout on sector ACK"); Syslog('x', "Timeout on sector ACK");
continue; continue;
case WANTCRC: case WANTCRC:
if (firstsec) if (firstsec)
Crcflg = TRUE; Crcflg = TRUE;
case NAK: case NAK:
Syslog('y', "NAK on sector"); Syslog('x', "NAK on sector");
continue; continue;
case ACK: case ACK:
firstsec=FALSE; firstsec=FALSE;
Totsecs += (cseclen>>7); Totsecs += (cseclen>>7);
return OK; return OK;
case TERROR: case TERROR:
Syslog('y', "Got burst for sector ACK"); Syslog('x', "Got burst for sector ACK");
break; break;
default: default:
Syslog('y', "Got %02x for sector ACK", firstch); Syslog('x', "Got %02x for sector ACK", firstch);
break; break;
} }
for (;;) { for (;;) {
@ -336,46 +429,25 @@ cancan:
goto cancan; goto cancan;
} }
} }
Syslog('y', "Retry Count Exceeded"); Syslog('x', "Retry Count Exceeded");
return ERROR; return TERROR;
} }
/* fill buf with count chars padding with ^Z for CPM */ /*
* fill buf with count chars padding with ^Z for CPM
*/
static size_t filbuf(char *buf, size_t count) static size_t filbuf(char *buf, size_t count)
{ {
int c;
size_t m; size_t m;
if ( !Ascii) { m = read(fileno(input_f), buf, count);
m = read(fileno(input_f), buf, count); if (m <= 0)
if (m <= 0) return 0;
return 0;
while (m < count) while (m < count)
buf[m++] = 032; buf[m++] = 032;
return count;
}
m=count;
if (Lfseen) {
*buf++ = 012; --m; Lfseen = 0;
}
while ((c=getc(input_f))!=EOF) {
if (c == 012) {
*buf++ = 015;
if (--m == 0) {
Lfseen = TRUE; break;
}
}
*buf++ =c;
if (--m == 0)
break;
}
if (m==count)
return 0;
else
while (m--!=0)
*buf++ = CPMEOF;
return count; return count;
} }

View File

@ -9,4 +9,7 @@
#define WANTCRC 0103 /* send C not NAK to get crc not checksum */ #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 WANTG 0107 /* Send G not NAK to get nonstop batch xmsn */
int ymsndfiles(down_list *, int);
#endif #endif

View File

@ -66,6 +66,7 @@ static inline void zsendline_s(const char *, int);
#include "../config.h" #include "../config.h"
#include "../lib/mbselib.h" #include "../lib/mbselib.h"
#include "ttyio.h" #include "ttyio.h"
#include "input.h"
#include "zmmisc.h" #include "zmmisc.h"
@ -956,20 +957,26 @@ long rclhdr(register char *shdr)
char *protname(void) char *protname(void)
{ {
const char *prot_name; switch (protocol) {
case ZM_XMODEM: return (char *)"Xmodem";
switch(protocol) { case ZM_YMODEM: return (char *)"Ymodem";
case ZM_XMODEM: default: return (char *)"Zmodem";
prot_name = (char *)"Xmodem";
break;
case ZM_YMODEM:
prot_name = (char *)"Ymodem";
break;
default:
prot_name = (char *)"Zmodem";
break;
} }
return prot_name; }
void purgeline(int howlong)
{
int c, count = 0;
unsigned char ch = 0;
do {
c = Waitchar(&ch, howlong);
count++;
} while (c == 1);
if (count)
Syslog('z', "purgeline: purged %d characters", count);
} }

View File

@ -159,6 +159,7 @@ void stohdr(long);
long rclhdr(register char *); long rclhdr(register char *);
void zsendline_init(void); void zsendline_init(void);
char *protname(void); char *protname(void);
void purgeline(int);
#define FTOFFSET 16 #define FTOFFSET 16

View File

@ -78,8 +78,7 @@ extern unsigned long rcvdbytes;
int zmrcvfiles(void) int zmrcvfiles(void)
{ {
int rc, c, count = 0; int rc;
unsigned char ch = 0;
Syslog('+', "Zmodem: start Zmodem receive"); Syslog('+', "Zmodem: start Zmodem receive");
@ -117,12 +116,7 @@ int zmrcvfiles(void)
/* /*
* Some programs send some garbage after the transfer, eat these. * Some programs send some garbage after the transfer, eat these.
*/ */
do { purgeline(100);
c = Waitchar(&ch, 100);
count++;
} while (c == 1);
if (count)
Syslog('z', "zmrcvfiles: purged %d garbage characters", count);
Syslog('z', "Zmodem: receive rc=%d",rc); Syslog('z', "Zmodem: receive rc=%d",rc);
return abs(rc); return abs(rc);