/* Send ZMODEM binary header hdr of type type */ void zsbhdr(int type, char *hdr) { vfile(F("zsbhdr: %s %lx"), frametypes[type+FTOFFSET], rclhdr(hdr)); /* if (type == ZDATA) for (n = Znulls; --n >=0; ) xsendline(0); */ xsendline(ZPAD); xsendline(ZDLE); //Pete (El Supremo) This looks wrong but it is correct - the code fails if == is used if ((Crc32t = Txfcs32)) { int n; UNSL long crc; xsendline(ZBIN32); zsendline(type); crc = 0xFFFFFFFFL; crc = UPDC32(type, crc); for (n=4; --n >= 0; ++hdr) { crc = UPDC32((0377 & *hdr), crc); zsendline(*hdr); } crc = ~crc; for (n=4; --n >= 0;) { zsendline((int)crc); crc >>= 8; } } else {
/* * Receive a file with ZMODEM protocol * Assumes file name frame is in secbuf */ static int rzfile(void) { int c, n; long last_rxbytes = 0; long not_printed = 0; last_bps = 0; Eofseen = FALSE; n = 20; rxbytes = 0l; if (procheader(secbuf) == ERROR) { return (tryzhdrtype = ZSKIP); } for (;;) { stohdr(rxbytes); zshhdr(ZRPOS, Txhdr); nxthdr: switch (c = zgethdr(Rxhdr, 0)) { default: vfile("lrzfile: zgethdr returned %d", c); return ERROR; case ZNAK: case TIMEOUT: if (--n < 0) { vfile("lrzfile: zgethdr returned %d", c); return ERROR; } case ZFILE: zrdata(secbuf, MAX_BLOCK); continue; case ZEOF: if (rclhdr(Rxhdr) != rxbytes) { /* * Ignore eof if it's at wrong place - force * a timeout because the eof might have gone * out before we sent our zrpos. */ errors = 0; goto nxthdr; } if (Verbose > 1) { int minleft = 0; int secleft = 0; last_bps = (rxbytes / timing(0)); if (last_bps > 0) { minleft = (Bytesleft - rxbytes) / last_bps / 60; secleft = ((Bytesleft - rxbytes) / last_bps) % 60; } fprintf(stderr, "\rBytes Received: %7ld/%7ld BPS:%-6d \r\n", rxbytes, Bytesleft, last_bps); } closeok = 1; if (closeit()) { tryzhdrtype = ZFERR; vfile("lrzfile: closeit returned <> 0"); return ERROR; } vfile("lrzfile: normal EOF"); return c; case ERROR: /* Too much garbage in header search error */ if (--n < 0) { vfile("lrzfile: zgethdr returned %d", c); return ERROR; } zmputs(Attn); continue; case ZSKIP: closeit(); vfile("lrzfile: Sender SKIPPED file"); return c; case ZDATA: if (rclhdr(Rxhdr) != rxbytes) { if (--n < 0) { return ERROR; } zmputs(Attn); continue; } moredata: if (Verbose > 1 && (not_printed > 7 || rxbytes > last_bps / 2 + last_rxbytes)) { int minleft = 0; int secleft = 0; last_bps = (rxbytes / timing(0)); if (last_bps > 0) { minleft = (Bytesleft - rxbytes) / last_bps / 60; secleft = ((Bytesleft - rxbytes) / last_bps) % 60; } fprintf(stderr, "\rBytes Received: %7ld/%7ld BPS:%-6d ETA %02d:%02d ", rxbytes, Bytesleft, last_bps, minleft, secleft); last_rxbytes = rxbytes; not_printed = 0; if (nodeinf != -1 && ((time(0) - lup) > 5)) { lseek(nodeinf, 0, SEEK_SET); nin.ddn_bpsrate = last_bps; sprintf(nin.ddn_activity, "UL: %-34.34s", myname); write(nodeinf, &nin, sizeof(struct DayDream_NodeInfo)); lup = time(0); } } else if (Verbose) not_printed++; switch (c = zrdata(secbuf, MAX_BLOCK)) { case ZCAN: vfile("lrzfile: zgethdr returned %d", c); return ERROR; case ERROR: /* CRC error */ if (--n < 0) { vfile ("lrzfile: zgethdr returned %d", c); return ERROR; } zmputs(Attn); continue; case TIMEOUT: if (--n < 0) { vfile ("lrzfile: zgethdr returned %d", c); return ERROR; } continue; case GOTCRCW: n = 20; putsec(secbuf, Rxcount); rxbytes += Rxcount; stohdr(rxbytes); zshhdr(ZACK, Txhdr); xsendline(XON); goto nxthdr; case GOTCRCQ: n = 20; putsec(secbuf, Rxcount); rxbytes += Rxcount; stohdr(rxbytes); zshhdr(ZACK, Txhdr); goto moredata; case GOTCRCG: n = 20; putsec(secbuf, Rxcount); rxbytes += Rxcount; goto moredata; case GOTCRCE: n = 20; putsec(secbuf, Rxcount); rxbytes += Rxcount; goto nxthdr; } } } }
/* * Receive a file with ZMODEM protocol * Assumes file name frame is in secbuf */ int rzfile(void) { int c, n; Eofseen=FALSE; rxbytes = 0l; if ((c = procheader(secbuf))) { return (tryzhdrtype = c); } n = 20; for (;;) { stohdr(rxbytes); zshhdr(ZRPOS, Txhdr); nxthdr: switch (c = zgethdr(Rxhdr)) { default: Syslog('z', "rzfile: Wrong header %d", c); if ( --n < 0) { Syslog('+', "Zmodem: wrong header %d", c); return TERROR; } continue; case ZCAN: Syslog('+', "Zmodem: sender CANcelled"); return TERROR; case ZNAK: if ( --n < 0) { Syslog('+', "Zmodem: Got ZNAK"); return TERROR; } continue; case TIMEOUT: if ( --n < 0) { Syslog('z', "Zmodem: TIMEOUT"); return TERROR; } continue; case ZFILE: zrdata(secbuf, MAXBLOCK); continue; case ZEOF: if (rclhdr(Rxhdr) != rxbytes) { /* * Ignore eof if it's at wrong place - force * a timeout because the eof might have gone * out before we sent our zrpos. */ errors = 0; goto nxthdr; } if (closeit(1)) { tryzhdrtype = ZFERR; Syslog('+', "Zmodem: error closing file"); return TERROR; } fout = NULL; Syslog('z', "rzfile: normal EOF"); return c; case HANGUP: Syslog('+', "Zmodem: Lost Carrier"); return TERROR; case TERROR: /* Too much garbage in header search error */ if (--n < 0) { Syslog('+', "Zmodem: Too many errors"); return TERROR; } zmputs(Attn); continue; case ZSKIP: Modtime = 1; closeit(1); Syslog('+', "Zmodem: Sender SKIPPED file"); return c; case ZDATA: if (rclhdr(Rxhdr) != rxbytes) { if ( --n < 0) { Syslog('+', "Zmodem: Data has bad address"); return TERROR; } zmputs(Attn); continue; } moredata: Nopper(); alarm_on(); switch (c = zrdata(secbuf, MAXBLOCK)) { case ZCAN: Syslog('+', "Zmodem: sender CANcelled"); return TERROR; case HANGUP: Syslog('+', "Zmodem: Lost Carrier"); return TERROR; case TERROR: /* CRC error */ if (--n < 0) { Syslog('+', "Zmodem: Too many errors"); return TERROR; } zmputs(Attn); continue; case TIMEOUT: if ( --n < 0) { Syslog('+', "Zmodem: TIMEOUT"); return TERROR; } continue; case GOTCRCW: n = 20; putsec(secbuf, Rxcount); rxbytes += Rxcount; stohdr(rxbytes); PUTCHAR(XON); zshhdr(ZACK, Txhdr); goto nxthdr; case GOTCRCQ: n = 20; putsec(secbuf, Rxcount); rxbytes += Rxcount; stohdr(rxbytes); zshhdr(ZACK, Txhdr); goto moredata; case GOTCRCG: n = 20; putsec(secbuf, Rxcount); rxbytes += Rxcount; goto moredata; case GOTCRCE: n = 20; putsec(secbuf, Rxcount); rxbytes += Rxcount; goto nxthdr; } } } }