aboutsummaryrefslogtreecommitdiff
path: root/miscutils/rx.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-08-02 19:45:31 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-08-02 19:45:31 +0200
commitdc9495df03f411d67eb46002670ffea12bdd32ba (patch)
treec0d8f4c7a2482f6564252638d2d5f3b1f05aacb2 /miscutils/rx.c
parent80a3418b8c96300826842f109cd297280d3fbe05 (diff)
downloadbusybox-w32-dc9495df03f411d67eb46002670ffea12bdd32ba.tar.gz
busybox-w32-dc9495df03f411d67eb46002670ffea12bdd32ba.tar.bz2
busybox-w32-dc9495df03f411d67eb46002670ffea12bdd32ba.zip
rx: strip padding from last block. closes bug 501.
function old new delta rx_main 876 974 +98 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils/rx.c')
-rw-r--r--miscutils/rx.c102
1 files changed, 59 insertions, 43 deletions
diff --git a/miscutils/rx.c b/miscutils/rx.c
index 94eb4522d..3a8b6a8fe 100644
--- a/miscutils/rx.c
+++ b/miscutils/rx.c
@@ -1,15 +1,12 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/*------------------------------------------------------------------------- 2/*
3 * Filename: xmodem.c
4 * Copyright: Copyright (C) 2001, Hewlett-Packard Company 3 * Copyright: Copyright (C) 2001, Hewlett-Packard Company
5 * Author: Christopher Hoover <ch@hpl.hp.com> 4 * Author: Christopher Hoover <ch@hpl.hp.com>
6 * Description: xmodem functionality for uploading of kernels 5 * Description: xmodem functionality for uploading of kernels
7 * and the like 6 * and the like
8 * Created at: Thu Dec 20 01:58:08 PST 2001 7 * Created at: Thu Dec 20 01:58:08 PST 2001
9 *-----------------------------------------------------------------------*/ 8 *
10/* 9 * xmodem functionality for uploading of kernels and the like
11 * xmodem.c: xmodem functionality for uploading of kernels and
12 * the like
13 * 10 *
14 * Copyright (C) 2001 Hewlett-Packard Laboratories 11 * Copyright (C) 2001 Hewlett-Packard Laboratories
15 * 12 *
@@ -26,6 +23,7 @@
26#define ACK 0x06 23#define ACK 0x06
27#define NAK 0x15 24#define NAK 0x15
28#define BS 0x08 25#define BS 0x08
26#define PAD 0x1A
29 27
30/* 28/*
31Cf: 29Cf:
@@ -44,69 +42,93 @@ Cf:
44 42
45static int read_byte(unsigned timeout) 43static int read_byte(unsigned timeout)
46{ 44{
47 char buf[1]; 45 unsigned char buf;
48 int n; 46 int n;
49 47
50 alarm(timeout); 48 alarm(timeout);
51 /* NOT safe_read! We want ALRM to interrupt us */ 49 /* NOT safe_read! We want ALRM to interrupt us */
52 n = read(read_fd, buf, 1); 50 n = read(read_fd, &buf, 1);
53 alarm(0); 51 alarm(0);
54 if (n == 1) 52 if (n == 1)
55 return (unsigned char)buf[0]; 53 return buf;
56 return -1; 54 return -1;
57} 55}
58 56
59static int receive(/*int read_fd, */int file_fd) 57static int receive(/*int read_fd, */int file_fd)
60{ 58{
61 unsigned char blockBuf[1024]; 59 unsigned char blockBuf[1024];
60 unsigned blockLength = 0;
62 unsigned errors = 0; 61 unsigned errors = 0;
63 unsigned wantBlockNo = 1; 62 unsigned wantBlockNo = 1;
64 unsigned length = 0; 63 unsigned length = 0;
65 int do_crc = 1; 64 int do_crc = 1;
66 char nak = 'C'; 65 char reply_char;
67 unsigned timeout = TIMEOUT_LONG; 66 unsigned timeout = TIMEOUT_LONG;
68 67
69 /* Flush pending input */ 68 /* Flush pending input */
70 tcflush(read_fd, TCIFLUSH); 69 tcflush(read_fd, TCIFLUSH);
71 70
72 /* Ask for CRC; if we get errors, we will go with checksum */ 71 /* Ask for CRC; if we get errors, we will go with checksum */
73 full_write(write_fd, &nak, 1); 72 reply_char = 'C';
73 full_write(write_fd, &reply_char, 1);
74 74
75 for (;;) { 75 for (;;) {
76 int blockBegin; 76 int blockBegin;
77 int blockNo, blockNoOnesCompl; 77 int blockNo, blockNoOnesCompl;
78 int blockLength; 78 int cksum_or_crc;
79 int cksum_crc; /* cksum OR crc */
80 int expected; 79 int expected;
81 int i,j; 80 int i, j;
82 81
83 blockBegin = read_byte(timeout); 82 blockBegin = read_byte(timeout);
84 if (blockBegin < 0) 83 if (blockBegin < 0)
85 goto timeout; 84 goto timeout;
86 85
86 /* If last block, remove padding */
87 if (blockBegin == EOT) {
88 /* Data blocks can be padded with ^Z characters */
89 /* This code tries to detect and remove them */
90 if (blockLength >= 3
91 && blockBuf[blockLength - 1] == PAD
92 && blockBuf[blockLength - 2] == PAD
93 && blockBuf[blockLength - 3] == PAD
94 ) {
95 while (blockLength
96 && blockBuf[blockLength - 1] == PAD
97 ) {
98 blockLength--;
99 }
100 }
101 }
102 /* Write previously received block */
103 if (blockLength) {
104 errno = 0;
105 if (full_write(file_fd, blockBuf, blockLength) != blockLength) {
106 bb_perror_msg("can't write to file");
107 goto fatal;
108 }
109 }
110
87 timeout = TIMEOUT; 111 timeout = TIMEOUT;
88 nak = NAK; 112 reply_char = NAK;
89 113
90 switch (blockBegin) { 114 switch (blockBegin) {
91 case SOH: 115 case SOH:
92 case STX: 116 case STX:
93 break; 117 break;
94
95 case EOT: 118 case EOT:
96 nak = ACK; 119 reply_char = ACK;
97 full_write(write_fd, &nak, 1); 120 full_write(write_fd, &reply_char, 1);
98 return length; 121 return length;
99
100 default: 122 default:
101 goto error; 123 goto error;
102 } 124 }
103 125
104 /* block no */ 126 /* Block no */
105 blockNo = read_byte(TIMEOUT); 127 blockNo = read_byte(TIMEOUT);
106 if (blockNo < 0) 128 if (blockNo < 0)
107 goto timeout; 129 goto timeout;
108 130
109 /* block no one's compliment */ 131 /* Block no, in one's complement form */
110 blockNoOnesCompl = read_byte(TIMEOUT); 132 blockNoOnesCompl = read_byte(TIMEOUT);
111 if (blockNoOnesCompl < 0) 133 if (blockNoOnesCompl < 0)
112 goto timeout; 134 goto timeout;
@@ -126,15 +148,15 @@ static int receive(/*int read_fd, */int file_fd)
126 } 148 }
127 149
128 if (do_crc) { 150 if (do_crc) {
129 cksum_crc = read_byte(TIMEOUT); 151 cksum_or_crc = read_byte(TIMEOUT);
130 if (cksum_crc < 0) 152 if (cksum_or_crc < 0)
131 goto timeout; 153 goto timeout;
132 cksum_crc = (cksum_crc << 8) | read_byte(TIMEOUT); 154 cksum_or_crc = (cksum_or_crc << 8) | read_byte(TIMEOUT);
133 if (cksum_crc < 0) 155 if (cksum_or_crc < 0)
134 goto timeout; 156 goto timeout;
135 } else { 157 } else {
136 cksum_crc = read_byte(TIMEOUT); 158 cksum_or_crc = read_byte(TIMEOUT);
137 if (cksum_crc < 0) 159 if (cksum_or_crc < 0)
138 goto timeout; 160 goto timeout;
139 } 161 }
140 162
@@ -155,9 +177,9 @@ static int receive(/*int read_fd, */int file_fd)
155 expected = expected ^ blockBuf[i] << 8; 177 expected = expected ^ blockBuf[i] << 8;
156 for (j = 0; j < 8; j++) { 178 for (j = 0; j < 8; j++) {
157 if (expected & 0x8000) 179 if (expected & 0x8000)
158 expected = expected << 1 ^ 0x1021; 180 expected = (expected << 1) ^ 0x1021;
159 else 181 else
160 expected = expected << 1; 182 expected = (expected << 1);
161 } 183 }
162 } 184 }
163 expected &= 0xffff; 185 expected &= 0xffff;
@@ -166,25 +188,19 @@ static int receive(/*int read_fd, */int file_fd)
166 expected += blockBuf[i]; 188 expected += blockBuf[i];
167 expected &= 0xff; 189 expected &= 0xff;
168 } 190 }
169 if (cksum_crc != expected) { 191 if (cksum_or_crc != expected) {
170 bb_error_msg(do_crc ? "crc error, expected 0x%04x, got 0x%04x" 192 bb_error_msg(do_crc ? "crc error, expected 0x%04x, got 0x%04x"
171 : "checksum error, expected 0x%02x, got 0x%02x", 193 : "checksum error, expected 0x%02x, got 0x%02x",
172 expected, cksum_crc); 194 expected, cksum_or_crc);
173 goto error; 195 goto error;
174 } 196 }
175 197
176 wantBlockNo++; 198 wantBlockNo++;
177 length += blockLength; 199 length += blockLength;
178
179 errno = 0;
180 if (full_write(file_fd, blockBuf, blockLength) != blockLength) {
181 bb_perror_msg("can't write to file");
182 goto fatal;
183 }
184 next: 200 next:
185 errors = 0; 201 errors = 0;
186 nak = ACK; 202 reply_char = ACK;
187 full_write(write_fd, &nak, 1); 203 full_write(write_fd, &reply_char, 1);
188 continue; 204 continue;
189 error: 205 error:
190 timeout: 206 timeout:
@@ -192,9 +208,9 @@ static int receive(/*int read_fd, */int file_fd)
192 if (errors == MAXERRORS) { 208 if (errors == MAXERRORS) {
193 /* Abort */ 209 /* Abort */
194 210
195 /* if were asking for crc, try again w/o crc */ 211 /* If were asking for crc, try again w/o crc */
196 if (nak == 'C') { 212 if (reply_char == 'C') {
197 nak = NAK; 213 reply_char = NAK;
198 errors = 0; 214 errors = 0;
199 do_crc = 0; 215 do_crc = 0;
200 goto timeout; 216 goto timeout;
@@ -209,7 +225,7 @@ static int receive(/*int read_fd, */int file_fd)
209 /* Flush pending input */ 225 /* Flush pending input */
210 tcflush(read_fd, TCIFLUSH); 226 tcflush(read_fd, TCIFLUSH);
211 227
212 full_write(write_fd, &nak, 1); 228 full_write(write_fd, &reply_char, 1);
213 } /* for (;;) */ 229 } /* for (;;) */
214} 230}
215 231