1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#include "libbb.h"
35
36#if ENABLE_UUDECODE
37static void FAST_FUNC read_stduu(FILE *src_stream, FILE *dst_stream, int flags UNUSED_PARAM)
38{
39 char *line;
40
41 for (;;) {
42 int encoded_len, str_len;
43 char *line_ptr, *dst;
44 size_t line_len;
45
46 line_len = 64 * 1024;
47 line = xmalloc_fgets_str_len(src_stream, "\n", &line_len);
48 if (!line)
49 break;
50
51
52
53
54 str_len = line_len;
55 while (--str_len >= 0
56 && (line[str_len] == '\n' || line[str_len] == '\r')
57 ) {
58 line[str_len] = '\0';
59 }
60
61 if (strcmp(line, "end") == 0) {
62 return;
63 }
64
65 line_ptr = line;
66 while (*line_ptr) {
67 *line_ptr = (*line_ptr - 0x20) & 0x3f;
68 line_ptr++;
69 }
70 str_len = line_ptr - line;
71
72 encoded_len = line[0] * 4 / 3;
73
74
75
76 if (str_len <= encoded_len) {
77 break;
78 }
79 if (encoded_len <= 0) {
80
81 free(line);
82 continue;
83 }
84 if (encoded_len > 60) {
85 bb_simple_error_msg_and_die("line too long");
86 }
87
88 dst = line;
89 line_ptr = line + 1;
90 do {
91
92 *dst++ = line_ptr[0] << 2 | line_ptr[1] >> 4;
93 encoded_len--;
94 if (encoded_len == 0) {
95 break;
96 }
97
98 *dst++ = line_ptr[1] << 4 | line_ptr[2] >> 2;
99 encoded_len--;
100 if (encoded_len == 0) {
101 break;
102 }
103
104 *dst++ = line_ptr[2] << 6 | line_ptr[3];
105 line_ptr += 4;
106 encoded_len -= 2;
107 } while (encoded_len > 0);
108 fwrite(line, 1, dst - line, dst_stream);
109 free(line);
110 }
111 bb_simple_error_msg_and_die("short file");
112}
113
114int uudecode_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
115int uudecode_main(int argc UNUSED_PARAM, char **argv)
116{
117 FILE *src_stream;
118 char *outname = NULL;
119 char *line;
120
121 getopt32(argv, "^" "o:" "\0" "?1", &outname);
122 argv += optind;
123
124 if (!argv[0])
125 *--argv = (char*)"-";
126 src_stream = xfopen_stdin(argv[0]);
127
128
129 while ((line = xmalloc_fgetline(src_stream)) != NULL) {
130 void FAST_FUNC (*decode_fn_ptr)(FILE *src, FILE *dst, int flags);
131 char *line_ptr;
132 FILE *dst_stream;
133 int mode;
134
135 if (is_prefixed_with(line, "begin-base64 ")) {
136 line_ptr = line + 13;
137 decode_fn_ptr = read_base64;
138 } else if (is_prefixed_with(line, "begin ")) {
139 line_ptr = line + 6;
140 decode_fn_ptr = read_stduu;
141 } else {
142 free(line);
143 continue;
144 }
145
146
147 mode = bb_strtou(line_ptr, NULL, 8);
148 if (outname == NULL) {
149 outname = strchr(line_ptr, ' ');
150 if (!outname)
151 break;
152 outname++;
153 trim(outname);
154 if (!outname[0])
155 break;
156 }
157 dst_stream = stdout;
158 if (NOT_LONE_DASH(outname)
159
160
161
162
163
164
165
166 && (!ENABLE_DESKTOP || strcmp(outname, "/dev/stdout") != 0)
167 ) {
168 dst_stream = xfopen_for_write(outname);
169 fchmod(fileno(dst_stream), mode & (S_IRWXU | S_IRWXG | S_IRWXO));
170 }
171 free(line);
172 decode_fn_ptr(src_stream, dst_stream, BASE64_FLAG_UU_STOP + BASE64_FLAG_NO_STOP_CHAR);
173
174 return EXIT_SUCCESS;
175 }
176 bb_simple_error_msg_and_die("no 'begin' line");
177}
178#endif
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217#if ENABLE_BASE32 || ENABLE_BASE64
218
219# if ENABLE_BASE32
220static void bb_b32encode(char *p, const void *src, int length)
221{
222#define tbl bb_uuenc_tbl_base32
223 const unsigned char *s = src;
224
225
226 while (length > 0) {
227 unsigned cur, next;
228
229 length--;
230 cur = *s++;
231 *p++ = tbl[cur >> 3];
232 cur &= 7;
233
234 next = 0;
235 if (--length >= 0)
236 next = *s++;
237 *p++ = tbl[(cur << 2) + (next >> 6)];
238 cur = next & 0x3f;
239
240 *p++ = tbl[cur >> 1];
241 cur &= 1;
242
243 next = 0;
244 if (--length >= 0)
245 next = *s++;
246 *p++ = tbl[(cur << 4) + (next >> 4)];
247 cur = next & 0xf;
248
249 next = 0;
250 if (--length >= 0)
251 next = *s++;
252 *p++ = tbl[(cur << 1) + (next >> 7)];
253 cur = next & 0x7f;
254
255 *p++ = tbl[cur >> 2];
256 cur &= 3;
257
258 next = 0;
259 if (--length >= 0)
260 next = *s++;
261 *p++ = tbl[(cur << 3) + (next >> 5)];
262 cur = next & 0x1f;
263
264 *p++ = tbl[cur];
265 }
266#undef tbl
267
268 *p = '\0';
269
270 length = ((-length) * 3) >> 1;
271 while (length--) {
272 *--p = '=';
273 }
274}
275# else
276void bb_b32encode(char *p, const void *src, int length);
277# endif
278
279int baseNUM_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
280int baseNUM_main(int argc UNUSED_PARAM, char **argv)
281{
282 FILE *src_stream;
283 unsigned opts;
284 unsigned col = 76;
285
286 opts = getopt32(argv, "^" "diw:+" "\0" "?1", &col);
287 argv += optind;
288
289 if (!argv[0])
290 *--argv = (char*)"-";
291 src_stream = xfopen_stdin(argv[0]);
292 if (opts & 1) {
293
294 int flags = (unsigned char)EOF;
295 if (ENABLE_BASE32 && (!ENABLE_BASE64 || applet_name[4] == '3'))
296 flags = ((unsigned char)EOF) | BASE64_32;
297 read_base64(src_stream, stdout, flags);
298 } else {
299 enum {
300 SRC_BUF_SIZE = 3 * 5 * 32,
301 DST_BUF_SIZE = 8 * ((SRC_BUF_SIZE + 4) / 5),
302 };
303
304
305
306
307
308 char dst_buf[((DST_BUF_SIZE + 16) | 0xf) + 1];
309#define src_buf (dst_buf + sizeof(dst_buf) - SRC_BUF_SIZE)
310 int src_fd, rem;
311
312 src_fd = fileno(src_stream);
313 rem = 0;
314 while (1) {
315 size_t size = full_read(src_fd, src_buf, SRC_BUF_SIZE);
316 if ((ssize_t)size < 0)
317 bb_simple_perror_msg_and_die(bb_msg_read_error);
318 if (size == 0) {
319 if (rem != 0) bb_putchar('\n');
320 break;
321 }
322
323
324 if (ENABLE_BASE32 && (!ENABLE_BASE64 || applet_name[4] == '3')) {
325 bb_b32encode(dst_buf, src_buf, size);
326 size = 8 * ((size + 4) / 5);
327 } else {
328 bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64);
329 size = 4 * ((size + 2) / 3);
330 }
331
332 if (col == 0) {
333 fputs_stdout(dst_buf);
334 } else {
335 char *result = dst_buf;
336 if (rem == 0)
337 rem = col;
338 while (1) {
339 int out = size < rem ? size : rem;
340 rem -= out;
341 printf(rem != 0 ? "%.*s" : "%.*s\n", out, result);
342 if (rem != 0)
343 break;
344 size -= out;
345 if (size == 0)
346 break;
347 result += out;
348 rem = col;
349 }
350 }
351 }
352#undef src_buf
353 }
354
355 fflush_stdout_and_exit(EXIT_SUCCESS);
356}
357#endif
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391