1: /*
2: * File: zmr.c 07-30-1989
3: * Copyright 1988, 1989 Omen Technology Inc All Rights Reserved
4: *
5: *
6: *
7: * This module implements ZMODEM Run Length Encoding, an
8: * extension that was not funded by the original Telenet
9: * development contract.
10: *
11: * This software may be freely used for non commercial and
12: * educational (didactic only) purposes. This software may also
13: * be freely used to support file transfer operations to or from
14: * licensed Omen Technology products. Any programs which use
15: * part or all of this software must be provided in source form
16: * with this notice intact except by written permission from Omen
17: * Technology Incorporated.
18: *
19: * Use of this software for commercial or administrative purposes
20: * except when exclusively limited to interfacing Omen Technology
21: * products requires a per port license payment of $20.00 US per
22: * port (less in quantity). Use of this code by inclusion,
23: * decompilation, reverse engineering or any other means
24: * constitutes agreement to these conditions and acceptance of
25: * liability to license the materials and payment of reasonable
26: * legal costs necessary to enforce this license agreement.
27: *
28: *
29: * Omen Technology Inc FAX: 503-621-3745
30: * Post Office Box 4681
31: * Portland OR 97208
32: *
33: * This code is made available in the hope it will be useful,
34: * BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
35: * DAMAGES OF ANY KIND.
36: *
37: * ZMODEM RLE compression and decompression functions
38: */
39:
40: /* Send data subpacket RLE encoded with 32 bit FCS */
41: zsdar32(buf, length, frameend)
42: char *buf;
43: {
44: register int c, l, n;
45: register UNSL long crc;
46:
47: crc = 0xFFFFFFFFL; l = *buf++ & 0377;
48: if (length == 1) {
49: zsendline(l); crc = UPDC32(l, crc);
50: if (l == ZRESC) {
51: zsendline(1); crc = UPDC32(1, crc);
52: }
53: } else {
54: for (n = 0; --length >= 0; ++buf) {
55: if ((c = *buf & 0377) == l && n < 126 && length>0) {
56: ++n; continue;
57: }
58: switch (n) {
59: case 0:
60: zsendline(l);
61: crc = UPDC32(l, crc);
62: if (l == ZRESC) {
63: zsendline(0100); crc = UPDC32(0100, crc);
64: }
65: l = c; break;
66: case 1:
67: if (l != ZRESC) {
68: zsendline(l); zsendline(l);
69: crc = UPDC32(l, crc);
70: crc = UPDC32(l, crc);
71: n = 0; l = c; break;
72: }
73: /* **** FALL THRU TO **** */
74: default:
75: zsendline(ZRESC); crc = UPDC32(ZRESC, crc);
76: if (l == 040 && n < 34) {
77: n += 036;
78: zsendline(n); crc = UPDC32(n, crc);
79: }
80: else {
81: n += 0101;
82: zsendline(n); crc = UPDC32(n, crc);
83: zsendline(l); crc = UPDC32(l, crc);
84: }
85: n = 0; l = c; break;
86: }
87: }
88: }
89: xsendline(ZDLE); xsendline(frameend);
90: crc = UPDC32(frameend, crc);
91:
92: crc = ~crc;
93: for (length=4; --length >= 0;) {
94: zsendline((int)crc); crc >>= 8;
95: }
96: }
97:
98:
99: /* Receive data subpacket RLE encoded with 32 bit FCS */
100: zrdatr32(buf, length)
101: register char *buf;
102: {
103: register int c;
104: register UNSL long crc;
105: register char *end;
106: register int d;
107:
108: crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length;
109: d = 0; /* Use for RLE decoder state */
110: while (buf <= end) {
111: if ((c = zdlread()) & ~0377) {
112: crcfoo:
113: switch (c) {
114: case GOTCRCE:
115: case GOTCRCG:
116: case GOTCRCQ:
117: case GOTCRCW:
118: d = c; c &= 0377;
119: crc = UPDC32(c, crc);
120: if ((c = zdlread()) & ~0377)
121: goto crcfoo;
122: crc = UPDC32(c, crc);
123: if ((c = zdlread()) & ~0377)
124: goto crcfoo;
125: crc = UPDC32(c, crc);
126: if ((c = zdlread()) & ~0377)
127: goto crcfoo;
128: crc = UPDC32(c, crc);
129: if ((c = zdlread()) & ~0377)
130: goto crcfoo;
131: crc = UPDC32(c, crc);
132: if (crc != 0xDEBB20E3) {
133: zperr(badcrc);
134: return ERROR;
135: }
136: Rxcount = length - (end - buf);
137: #ifndef DSZ
138: vfile("zrdatr32: %d %s", Rxcount,
139: Zendnames[d-GOTCRCE&3]);
140: #endif
141: return d;
142: case GOTCAN:
143: zperr("Sender Canceled");
144: return ZCAN;
145: case TIMEOUT:
146: zperr("TIMEOUT");
147: return c;
148: default:
149: zperr("Bad data subpacket");
150: return c;
151: }
152: }
153: crc = UPDC32(c, crc);
154: switch (d) {
155: case 0:
156: if (c == ZRESC) {
157: d = -1; continue;
158: }
159: *buf++ = c; continue;
160: case -1:
161: if (c >= 040 && c < 0100) {
162: d = c - 035; c = 040; goto spaces;
163: }
164: if (c == 0100) {
165: d = 0;
166: *buf++ = ZRESC; continue;
167: }
168: d = c; continue;
169: default:
170: d -= 0100;
171: if (d < 1)
172: goto badpkt;
173: spaces:
174: if ((buf + d) > end)
175: goto badpkt;
176: while ( --d >= 0)
177: *buf++ = c;
178: d = 0; continue;
179: }
180: }
181: badpkt:
182: zperr("Data subpacket too long");
183: return ERROR;
184: }
Defined functions
Usage of this include