?? zm.c
字號(hào):
/* * Z M . C * Copyright 1994 Omen Technology Inc All Rights Reserved * ZMODEM protocol primitives * * Entry point Functions: * zsbhdr(type, hdr) send binary header * zshhdr(type, hdr) send hex header * zgethdr(hdr) receive header - binary or hex * zsdata(buf, len, frameend) send data * zrdata(buf, len) receive data * stohdr(pos) store position data in Txhdr * long rclhdr(hdr) recover position offset from header * * * This version implements numerous enhancements including ZMODEM * Run Length Encoding and variable length headers. These * features were not funded by the original Telenet development * contract. * * This software may be freely used for educational (didactic * only) purposes. This software may also be freely used to * support file transfer operations to or from licensed Omen * Technology products. Use with other commercial or shareware * programs (Crosstalk, Procomm, etc.) REQUIRES REGISTRATION. * * Any programs which use part or all of this software must be * provided in source form with this notice intact except by * written permission from Omen Technology Incorporated. * * Use of this software for commercial or administrative purposes * except when exclusively limited to interfacing Omen Technology * products requires a per port license payment of $20.00 US per * port (less in quantity). Use of this code by inclusion, * decompilation, reverse engineering or any other means * constitutes agreement to these conditions and acceptance of * liability to license the materials and payment of reasonable * legal costs necessary to enforce this license agreement. * * * Omen Technology Inc * Post Office Box 4681 * Portland OR 97208 * * This code is made available in the hope it will be useful, * BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY * DAMAGES OF ANY KIND. * */#ifndef CANFDX#include "zmodem.h"int Rxtimeout = 100; /* Tenths of seconds to wait for something */#endif/* Globals used by ZMODEM functions */int Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame */int Rxtype; /* Type of header received */int Rxhlen; /* Length of header received */int Rxcount; /* Count of data bytes received */char Rxhdr[ZMAXHLEN]; /* Received header */char Txhdr[ZMAXHLEN]; /* Transmitted header */long Rxpos; /* Received file position */long Txpos; /* Transmitted file position */int Txfcs32; /* TURE means send binary frames with 32 bit FCS */int Crc32t; /* Controls 32 bit CRC being sent */ /* 1 == CRC32, 2 == CRC32 + RLE */int Crc32r; /* Indicates/controls 32 bit CRC being received */ /* 0 == CRC16, 1 == CRC32, 2 == CRC32 + RLE */int Usevhdrs; /* Use variable length headers */int Znulls; /* Number of nulls to send at beginning of ZDATA hdr */char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */char *Altcan; /* Alternate canit string */static lastsent; /* Last char we sent */static char *frametypes[] = { "No Response to Error Correction Request", /* -4 */ "No Carrier Detect", /* -3 */ "TIMEOUT", /* -2 */ "ERROR", /* -1 */#define FTOFFSET 4 "ZRQINIT", "ZRINIT", "ZSINIT", "ZACK", "ZFILE", "ZSKIP", "ZNAK", "ZABORT", "ZFIN", "ZRPOS", "ZDATA", "ZEOF", "ZFERR", "ZCRC", "ZCHALLENGE", "ZCOMPL", "ZCAN", "ZFREECNT", "ZCOMMAND", "ZSTDERR", "xxxxx"#define FRTYPES 22 /* Total number of frame types in this array */ /* not including psuedo negative entries */};static char badcrc[] = "Bad CRC";/* Send ZMODEM binary header hdr of type type */zsbhdr(len, type, hdr)register char *hdr;{ register int n; register unsigned short crc;#ifndef DSZ vfile("zsbhdr: %c %d %s %lx", Usevhdrs?'v':'f', len, frametypes[type+FTOFFSET], rclhdr(hdr));#endif if (type == ZDATA) for (n = Znulls; --n >=0; ) xsendline(0); xsendline(ZPAD); xsendline(ZDLE); switch (Crc32t=Txfcs32) { case 2: zsbh32(len, hdr, type, Usevhdrs?ZVBINR32:ZBINR32); flushmo(); break; case 1: zsbh32(len, hdr, type, Usevhdrs?ZVBIN32:ZBIN32); break; default: if (Usevhdrs) { xsendline(ZVBIN); zsendline(len); } else xsendline(ZBIN); zsendline(type); crc = updcrc(type, 0); for (n=len; --n >= 0; ++hdr) { zsendline(*hdr); crc = updcrc((0377& *hdr), crc); } crc = updcrc(0,updcrc(0,crc)); zsendline(((int)(crc>>8))); zsendline(crc); } if (type != ZDATA) flushmo();}/* Send ZMODEM binary header hdr of type type */zsbh32(len, hdr, type, flavour)register char *hdr;{ register int n; register unsigned long crc; xsendline(flavour); if (Usevhdrs) zsendline(len); zsendline(type); crc = 0xFFFFFFFFL; crc = UPDC32(type, crc); for (n=len; --n >= 0; ++hdr) { crc = UPDC32((0377 & *hdr), crc); zsendline(*hdr); } crc = ~crc; for (n=4; --n >= 0;) { zsendline((int)crc); crc >>= 8; }}/* Send ZMODEM HEX header hdr of type type */zshhdr(len, type, hdr)register char *hdr;{ register int n; register unsigned short crc;#ifndef DSZ vfile("zshhdr: %c %d %s %lx", Usevhdrs?'v':'f', len, frametypes[type+FTOFFSET], rclhdr(hdr));#endif sendline(ZPAD); sendline(ZPAD); sendline(ZDLE); if (Usevhdrs) { sendline(ZVHEX); zputhex(len); } else sendline(ZHEX); zputhex(type); Crc32t = 0; crc = updcrc(type, 0); for (n=len; --n >= 0; ++hdr) { zputhex(*hdr); crc = updcrc((0377 & *hdr), crc); } crc = updcrc(0,updcrc(0,crc)); zputhex(((int)(crc>>8))); zputhex(crc); /* Make it printable on remote machine */ sendline(015); sendline(0212); /* * Uncork the remote in case a fake XOFF has stopped data flow */ if (type != ZFIN && type != ZACK) sendline(021); flushmo();}/* * Send binary array buf of length length, with ending ZDLE sequence frameend */static char *Zendnames[] = { "ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"};zsdata(buf, length, frameend)register char *buf;{ register unsigned short crc;#ifndef DSZ vfile("zsdata: %d %s", length, Zendnames[frameend-ZCRCE&3]);#endif switch (Crc32t) { case 1: zsda32(buf, length, frameend); break; case 2: zsdar32(buf, length, frameend); break; default: crc = 0; for (;--length >= 0; ++buf) { zsendline(*buf); crc = updcrc((0377 & *buf), crc); } xsendline(ZDLE); xsendline(frameend); crc = updcrc(frameend, crc); crc = updcrc(0,updcrc(0,crc)); zsendline(((int)(crc>>8))); zsendline(crc); } if (frameend == ZCRCW) xsendline(XON); if (frameend != ZCRCG) flushmo();}zsda32(buf, length, frameend)register char *buf;{ register int c; register unsigned long crc; crc = 0xFFFFFFFFL; for (;--length >= 0; ++buf) { c = *buf & 0377; zsendline(c); crc = UPDC32(c, crc); } xsendline(ZDLE); xsendline(frameend); crc = UPDC32(frameend, crc); crc = ~crc; for (c=4; --c >= 0;) { zsendline((int)crc); crc >>= 8; }}/* * Receive array buf of max length with ending ZDLE sequence * and CRC. Returns the ending character or error code. * NB: On errors may store length+1 bytes! */zrdata(buf, length)register char *buf;{ register int c; register unsigned short crc; register char *end; register int d; switch (Crc32r) { case 1: return zrdat32(buf, length); case 2: return zrdatr32(buf, length); } crc = Rxcount = 0; end = buf + length; while (buf <= end) { if ((c = zdlread()) & ~0377) {crcfoo: switch (c) { case GOTCRCE: case GOTCRCG: case GOTCRCQ: case GOTCRCW: crc = updcrc((d=c)&0377, crc); if ((c = zdlread()) & ~0377) goto crcfoo; crc = updcrc(c, crc); if ((c = zdlread()) & ~0377) goto crcfoo; crc = updcrc(c, crc); if (crc & 0xFFFF) { zperr1(badcrc); return ERROR; } Rxcount = length - (end - buf);#ifndef DSZ vfile("zrdata: %d %s", Rxcount, Zendnames[d-GOTCRCE&3]);#endif return d; case GOTCAN: zperr1("Sender Canceled"); return ZCAN; case TIMEOUT: zperr1("TIMEOUT"); return c; default: garbitch(); return c; } } *buf++ = c; crc = updcrc(c, crc); }#ifdef DSZ garbitch(); #else zperr1("Data subpacket too long");#endif return ERROR;}zrdat32(buf, length)register char *buf;{ register int c; register unsigned long crc; register char *end; register int d; crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length; while (buf <= end) { if ((c = zdlread()) & ~0377) {crcfoo: switch (c) { case GOTCRCE: case GOTCRCG: case GOTCRCQ: case GOTCRCW: d = c; c &= 0377; crc = UPDC32(c, crc); if ((c = zdlread()) & ~0377) goto crcfoo; crc = UPDC32(c, crc); if ((c = zdlread()) & ~0377) goto crcfoo; crc = UPDC32(c, crc); if ((c = zdlread()) & ~0377) goto crcfoo; crc = UPDC32(c, crc); if ((c = zdlread()) & ~0377) goto crcfoo; crc = UPDC32(c, crc); if (crc != 0xDEBB20E3) { zperr1(badcrc); return ERROR; } Rxcount = length - (end - buf);#ifndef DSZ vfile("zrdat32: %d %s", Rxcount, Zendnames[d-GOTCRCE&3]);#endif return d; case GOTCAN: zperr1("Sender Canceled"); return ZCAN; case TIMEOUT: zperr1("TIMEOUT"); return c; default: garbitch(); return c; } } *buf++ = c; crc = UPDC32(c, crc); } zperr1("Data subpacket too long"); return ERROR;}garbitch(){ zperr1("Garbled data subpacket");}/* * Read a ZMODEM header to hdr, either binary or hex. * * Set Rxhlen to size of header (default 4) (valid iff good hdr) * On success, set Zmodem to 1, set Rxpos and return type of header. * Otherwise return negative on error. * Return ERROR instantly if ZCRCW sequence, for fast error recovery. */zgethdr(hdr)char *hdr;{ register int c, n, cancount; n = Zrwindow + Baudrate; Rxframeind = Rxtype = 0;startover: cancount = 5;again: switch (c = readline(Rxtimeout)) { case 021: case 0221: goto again; case RCDO: case TIMEOUT: goto fifi; case CAN:gotcan: if (--cancount <= 0) { c = ZCAN; goto fifi; } switch (c = readline(Rxtimeout)) { case TIMEOUT: goto again; case ZCRCW: switch (readline(Rxtimeout)) { case TIMEOUT: c = ERROR; goto fifi; case RCDO:
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -