diff --git a/mbsebbs/Makefile b/mbsebbs/Makefile index 83dfe3a7..1715c5a9 100644 --- a/mbsebbs/Makefile +++ b/mbsebbs/Makefile @@ -133,8 +133,8 @@ 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 ymrecv.h +ymrecv.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ttyio.h zmmisc.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 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 # End of generated dependencies diff --git a/mbsebbs/ymrecv.c b/mbsebbs/ymrecv.c index 29028fdc..5494ebae 100644 --- a/mbsebbs/ymrecv.c +++ b/mbsebbs/ymrecv.c @@ -31,6 +31,143 @@ #include "../config.h" #include "../lib/mbselib.h" #include "../lib/mbse.h" +#include "ttyio.h" +#include "zmmisc.h" #include "ymrecv.h" + +static int Firstsec; +static int eof_seen; +static int errors; + +extern int Crcflg; +extern char Lastrx; + +#define sendline(c) PUTCHAR((c) & 0377) + +int wcgetsec(size_t *, char *, unsigned int); + +int wcrxpn(char *rpn) +{ + register int c; + size_t Blklen = 0; /* record length of received packets */ + + purgeline(0); + +et_tu: + Firstsec = TRUE; + eof_seen = FALSE; + sendline(Crcflg?WANTCRC:NAK); + fflush(stdout); + purgeline(0); /* Do read next time ... */ + while ((c = wcgetsec(&Blklen, rpn, 100)) != 0) { + if (c == WCEOT) { + Syslog('x', "Pathname fetch returned EOT"); + sendline(ACK); + fflush(stdout); + purgeline(0); /* Do read next time ... */ + GETCHAR(1); + goto et_tu; + } + return ERROR; + } + sendline(ACK); + fflush(stdout); + return OK; +} + + + +int wcrx(void) +{ +} + + +int wcgetsec(size_t *Blklen, char *rxbuf, unsigned int maxtime) +{ + register int Checksum, wcj, firstch; + register unsigned short oldcrc; + register char *p; + int sectcurr; + + for (Lastrx = errors = 0; errors < RETRYMAX; errors++) { + + if ((firstch = GETCHAR(maxtime)) == STX) { + *Blklen = 1024; goto get2; + } + if (firstch == SOH) { + *Blklen=128; +get2: + sectcurr = GETCHAR(1); + if ((sectcurr + (oldcrc = GETCHAR(1))) == 0377) { + oldcrc = Checksum = 0; + for (p = rxbuf, wcj = *Blklen; --wcj >= 0; ) { + if ((firstch = GETCHAR(1)) < 0) + goto bilge; + oldcrc = updcrc16(firstch, oldcrc); + Checksum += (*p++ = firstch); + } + if ((firstch = GETCHAR(1)) < 0) + goto bilge; + if (Crcflg) { + oldcrc = updcrc16(firstch, oldcrc); + if ((firstch = GETCHAR(1)) < 0) + goto bilge; + oldcrc = updcrc16(firstch, oldcrc); + if (oldcrc & 0xFFFF) + Syslog('x', "CRC"); + else { + Firstsec=FALSE; + return sectcurr; + } + } else if (((Checksum - firstch) & 0377) == 0) { + Firstsec = FALSE; + return sectcurr; + } else + Syslog('x', "Checksum"); + } else + Syslog('x', "Sector number garbled"); + } + /* make sure eot really is eot and not just mixmash */ + else if (firstch == EOT && GETCHAR(1) == TIMEOUT) + return WCEOT; + else if (firstch == CAN) { + if (Lastrx == CAN) { + Syslog('x', "Sender Cancelled"); + return ERROR; + } else { + Lastrx=CAN; + continue; + } + } else if (firstch == TIMEOUT) { + if (Firstsec) + goto humbug; +bilge: + Syslog('x', "TIMEOUT"); + } else + Syslog('x', "Got 0%o sector header", firstch); +humbug: + Lastrx = 0; + { + int cnt = 1000; + while (cnt-- && GETCHAR(1) != TIMEOUT); + } + + if (Firstsec) { + sendline(Crcflg ? WANTCRC:NAK); + fflush(stdout); + purgeline(0); /* Do read next time ... */ + } else { + maxtime = 40; + sendline(NAK); + fflush(stdout); + purgeline(0); /* Do read next time ... */ + } + } + /* try to stop the bubble machine. */ + canit(STDOUT_FILENO); + return ERROR; +} + + diff --git a/mbsebbs/ymrecv.h b/mbsebbs/ymrecv.h index 41225d75..f031405d 100644 --- a/mbsebbs/ymrecv.h +++ b/mbsebbs/ymrecv.h @@ -3,4 +3,12 @@ /* $Id$ */ +#define WANTCRC 0103 /* send C not NAK to get crc not checksum */ +#define WCEOT (-10) + +#define RETRYMAX 10 + +int wcrxpn(char *); +int wcrx(void); + #endif diff --git a/mbsebbs/ymsend.c b/mbsebbs/ymsend.c index dbed96d0..d98398d0 100644 --- a/mbsebbs/ymsend.c +++ b/mbsebbs/ymsend.c @@ -56,7 +56,7 @@ int Optiong; /* Let it rip no wait for sector ACK's */ int Totsecs; /* total number of sectors this file */ char *txbuf; size_t blklen = 128; /* length of transmitted records */ -int zmodem_requested = 0; +int zmodem_requested = FALSE; static int no_unixmode; struct timeval starttime, endtime; struct timezone tz; @@ -189,7 +189,7 @@ static int wctxpn(char *fname) f.st_mode = 0; } -// if (!zmodem_requested) + if (!zmodem_requested) if (getnak()) { PUTSTR((char *)"getnak failed"); Syslog('+', "%s/%s: getnak failed", MBSE_SS(fname), protname()); diff --git a/mbsebbs/zmmisc.c b/mbsebbs/zmmisc.c index 2e2e18bc..0b28b54b 100644 --- a/mbsebbs/zmmisc.c +++ b/mbsebbs/zmmisc.c @@ -82,6 +82,7 @@ static int Not8bit; /* Seven bits seen on header */ static char zsendline_tab[256]; extern unsigned Baudrate; +extern int zmodem_requested; char *frametypes[] = { @@ -585,6 +586,7 @@ int zrbhdr(register char *shdr) return TERROR; } + zmodem_requested = TRUE; protocol = ZM_ZMODEM; return Rxtype; } @@ -620,6 +622,7 @@ int zrbhd32(register char *shdr) return TERROR; } + zmodem_requested = TRUE; protocol = ZM_ZMODEM; return Rxtype; } @@ -668,6 +671,7 @@ int zrhhdr(char *shdr) if (c < 0) return c; + zmodem_requested = TRUE; protocol = ZM_ZMODEM; return Rxtype; } @@ -980,4 +984,18 @@ void purgeline(int howlong) } +/* + * send cancel string to get the other end to shut up + */ +void canit(int fd) +{ + static char canistr[] = { 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0 }; + + ioctl(fd, TCFLSH, 0); + write(fd, canistr, strlen(canistr)); + if (fd == 0) + write(1, canistr, strlen(canistr)); +} + + /* End of zmmisc.c */ diff --git a/mbsebbs/zmmisc.h b/mbsebbs/zmmisc.h index bca41249..ccd73855 100644 --- a/mbsebbs/zmmisc.h +++ b/mbsebbs/zmmisc.h @@ -160,7 +160,7 @@ long rclhdr(register char *); void zsendline_init(void); char *protname(void); void purgeline(int); - +void canit(int); #define FTOFFSET 16 diff --git a/mbsebbs/zmrecv.c b/mbsebbs/zmrecv.c index e862e0ac..399fd5d7 100644 --- a/mbsebbs/zmrecv.c +++ b/mbsebbs/zmrecv.c @@ -35,6 +35,7 @@ #include "transfer.h" #include "zmmisc.h" #include "zmrecv.h" +#include "ymrecv.h" #include "openport.h" #include "timeout.h" #include "input.h" @@ -73,7 +74,7 @@ static long getfree(void); extern unsigned long rcvdbytes; - +extern int zmodem_requested; int zmrcvfiles(void) @@ -92,8 +93,31 @@ int zmrcvfiles(void) Syslog('+', "Zmodem: could not initiate receive, rc=%d",rc); } else { if (rc == 0) { - /* Check for ymodem sector */ + if (wcrxpn(secbuf) == TERROR) { + rc = 2; + goto fubar; + } + /* + * Enter X/Y modem receive loop + */ + for (;;) { + if (secbuf[0] == 0) { + Syslog('z', "%s: seems complete", protname()); + goto fubar; + } + if (procheader(secbuf) == ZFERR) { + rc = 2; + goto fubar; + } + if (wcrx() == TERROR) { + rc = 2; + goto fubar; + } + } } + /* + * Zmodem receiver + */ switch (rc) { case ZCOMPL: rc = 0; break; @@ -102,6 +126,7 @@ int zmrcvfiles(void) } } +fubar: if (fout) { if (closeit(0)) { WriteError("Zmodem: Error closing file"); @@ -138,7 +163,7 @@ int tryz(void) if (protocol != ZM_ZMODEM) return 0; - for (n = 15; --n >= 0; ) { + for (n = zmodem_requested ?15:5; --n >= 0; ) { /* * Set buffer length (0) and capability flags */