/* * 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; }