/* * 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; } } } }
/* * Initialize for Zmodem receive attempt, try to activate Zmodem sender * Handles ZSINIT frame * Return ZFILE if Zmodem filename received, -1 on error, * ZCOMPL if transaction finished, else 0 */ static int tryz(void) { int c, n; int cmdzack1flg; for (n = Zmodem ? 15 : 5; --n >= 0;) { /* Set buffer length (0) and capability flags */ stohdr(0L); Txhdr[ZF0] = CANFC32 | CANFDX | CANOVIO | CANBRK; if (Zctlesc) Txhdr[ZF0] |= TESCCTL; /* TESCCTL == ESCCTL */ zshhdr(tryzhdrtype, Txhdr); if (tryzhdrtype == ZSKIP) /* Don't skip too far */ tryzhdrtype = ZRINIT; /* CAF 8-21-87 */ again: switch (zgethdr(Rxhdr, 0)) { case ZRQINIT: continue; case ZEOF: continue; case TIMEOUT: continue; case ZFILE: zconv = Rxhdr[ZF0]; zmanag = Rxhdr[ZF1]; ztrans = Rxhdr[ZF2]; tryzhdrtype = ZRINIT; c = zrdata(secbuf, MAX_BLOCK); mode(3); if (c == GOTCRCW) return ZFILE; zshhdr(ZNAK, Txhdr); goto again; case ZSINIT: Zctlesc = TESCCTL & Rxhdr[ZF0]; if (zrdata(Attn, ZATTNLEN) == GOTCRCW) { stohdr(1L); zshhdr(ZACK, Txhdr); goto again; } zshhdr(ZNAK, Txhdr); goto again; case ZFREECNT: stohdr(getfree()); zshhdr(ZACK, Txhdr); goto again; case ZCOMMAND: cmdzack1flg = Rxhdr[ZF0]; if (zrdata(secbuf, MAX_BLOCK) == GOTCRCW) { if (Verbose) { fprintf(stderr, "lrz: remote requested command\n"); fprintf(stderr, "lrz: %s\n", secbuf); } if (Verbose) fprintf(stderr, "lrz: not executed\n"); zshhdr(ZCOMPL, Txhdr); return ZCOMPL; } goto again; case ZCOMPL: goto again; default: continue; case ZFIN: ackbibi(); return ZCOMPL; case ZCAN: return ERROR; } } return 0; }
/* * Initialize for Zmodem receive attempt, try to activate Zmodem sender * Handles ZSINIT frame * Return ZFILE if Zmodem filename received, -1 on error, * ZCOMPL if transaction finished, else 0: can be ymodem. */ int tryz(void) { int c, n; int cmdzack1flg; if (protocol != ZM_ZMODEM) return 0; for (n = zmodem_requested ?15:10; --n >= 0; ) { /* * Set buffer length (0) and capability flags */ Syslog('z', "tryz attempt %d", n); stohdr(0L); Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO; if (Zctlesc) Txhdr[ZF0] |= TESCCTL; zshhdr(tryzhdrtype, Txhdr); if (tryzhdrtype == ZSKIP) /* Don't skip too far */ tryzhdrtype = ZRINIT; /* CAF 8-21-87 */ again: switch (zgethdr(Rxhdr)) { case ZRQINIT: continue; case ZEOF: continue; case TIMEOUT: Syslog('z', "Zmodem: tryz() timeout attempt %d", n); continue; case ZFILE: zconv = Rxhdr[ZF0]; if (!zconv) { Syslog('z', "*** !zconv %d", zconv); zconv = ZCBIN; } zmanag = Rxhdr[ZF1]; ztrans = Rxhdr[ZF2]; tryzhdrtype = ZRINIT; c = zrdata(secbuf, MAXBLOCK); io_mode(0, 3); if (c == GOTCRCW) { Syslog('z', "tryz return ZFILE"); return ZFILE; } zshhdr(ZNAK, Txhdr); goto again; case ZSINIT: /* this once was: * Zctlesc = TESCCTL & Rxhdr[ZF0]; * trouble: if rz get --escape flag: * - it sends TESCCTL to sz, * get a ZSINIT _without_ TESCCTL (yeah - sender didn't know), * overwrites Zctlesc flag ... * - sender receives TESCCTL and uses "|=..." * so: sz escapes, but rz doesn't unescape ... not good. */ Zctlesc |= TESCCTL & Rxhdr[ZF0]; if (zrdata(Attn, ZATTNLEN) == GOTCRCW) { stohdr(1L); zshhdr(ZACK, Txhdr); goto again; } zshhdr(ZNAK, Txhdr); goto again; case ZFREECNT: stohdr(getfree()); zshhdr(ZACK, Txhdr); goto again; case ZCOMMAND: cmdzack1flg = Rxhdr[ZF0]; if (zrdata(secbuf, MAXBLOCK) == GOTCRCW) { if (cmdzack1flg & ZCACK1) stohdr(0L); else Syslog('+', "Zmodem: request for command \"%s\" ignored", printable(secbuf,-32)); stohdr(0L); do { zshhdr(ZCOMPL, Txhdr); } while (++errors<20 && zgethdr(Rxhdr) != ZFIN); return ackbibi(); } zshhdr(ZNAK, Txhdr); goto again; case ZCOMPL: goto again; case ZRINIT: Syslog('z', "tryz: got ZRINIT"); return TERROR; case ZFIN: /* do not beleive in first ZFIN */ ackbibi(); return ZCOMPL; case TERROR: case HANGUP: case ZCAN: return TERROR; default: continue; } } return 0; }