aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2010-09-16 17:51:13 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2010-09-16 17:51:13 +0200
commit9fe98f701d40835db32baa12c94b661d40231ea4 (patch)
tree781c9c71519f3eb79082eac54e0cc545e16b2fd1
parent52e460b7440ed5b85e4125a4eccf1e665d92c0ff (diff)
downloadbusybox-w32-9fe98f701d40835db32baa12c94b661d40231ea4.tar.gz
busybox-w32-9fe98f701d40835db32baa12c94b661d40231ea4.tar.bz2
busybox-w32-9fe98f701d40835db32baa12c94b661d40231ea4.zip
libbb: merge mail and uudecode's base64 decoders
function old new delta read_base64 - 378 +378 uudecode_main 306 315 +9 parse 953 958 +5 read_stduu 250 254 +4 base64_main 217 219 +2 read_base64 358 - -358 decode_base64 371 - -371 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 4/0 up/down: 398/-729) Total: -331 bytes Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rw-r--r--coreutils/uudecode.c73
-rw-r--r--include/libbb.h6
-rw-r--r--libbb/base64.c78
-rw-r--r--mailutils/mail.c67
-rw-r--r--mailutils/mail.h1
-rw-r--r--mailutils/mime.c4
6 files changed, 90 insertions, 139 deletions
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c
index 0da9b0988..0c4311f24 100644
--- a/coreutils/uudecode.c
+++ b/coreutils/uudecode.c
@@ -13,7 +13,7 @@
13#include "libbb.h" 13#include "libbb.h"
14 14
15#if ENABLE_UUDECODE 15#if ENABLE_UUDECODE
16static void read_stduu(FILE *src_stream, FILE *dst_stream) 16static void FAST_FUNC read_stduu(FILE *src_stream, FILE *dst_stream, int flags UNUSED_PARAM)
17{ 17{
18 char *line; 18 char *line;
19 19
@@ -75,71 +75,6 @@ static void read_stduu(FILE *src_stream, FILE *dst_stream)
75} 75}
76#endif 76#endif
77 77
78static void read_base64(FILE *src_stream, FILE *dst_stream)
79{
80 int term_count = 0;
81
82 while (1) {
83 unsigned char translated[4];
84 int count = 0;
85
86 /* Process one group of 4 chars */
87 while (count < 4) {
88 char *table_ptr;
89 int ch;
90
91 /* Get next _valid_ character.
92 * bb_uuenc_tbl_base64[] contains this string:
93 * 0 1 2 3 4 5 6
94 * 012345678901234567890123456789012345678901234567890123456789012345
95 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"
96 */
97 do {
98 ch = fgetc(src_stream);
99 if (ch == EOF) {
100 if (ENABLE_BASE64
101 && (!ENABLE_UUDECODE || applet_name[0] == 'b')
102 && count == 0
103 ) {
104 return;
105 }
106 bb_error_msg_and_die("short file");
107 }
108 table_ptr = strchr(bb_uuenc_tbl_base64, ch);
109 } while (!table_ptr);
110
111 /* Convert encoded character to decimal */
112 ch = table_ptr - bb_uuenc_tbl_base64;
113
114 if (ch == 65 /* '\n' */) {
115 /* Terminating "====" line? */
116 if (term_count == 4)
117 return; /* yes */
118 term_count = 0;
119 continue;
120 }
121 /* ch is 64 is char was '=', otherwise 0..63 */
122 translated[count] = ch & 63; /* 64 -> 0 */
123 if (ch == 64) {
124 term_count++;
125 break;
126 }
127 count++;
128 }
129
130 /* Merge 6 bit chars to 8 bit.
131 * count can be < 4 when we decode the tail:
132 * "eQ==" -> "y", not "y NUL NUL"
133 */
134 if (count > 1)
135 fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
136 if (count > 2)
137 fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
138 if (count > 3)
139 fputc(translated[2] << 6 | translated[3], dst_stream);
140 } /* while (1) */
141}
142
143#if ENABLE_UUDECODE 78#if ENABLE_UUDECODE
144int uudecode_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 79int uudecode_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
145int uudecode_main(int argc UNUSED_PARAM, char **argv) 80int uudecode_main(int argc UNUSED_PARAM, char **argv)
@@ -158,7 +93,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv)
158 93
159 /* Search for the start of the encoding */ 94 /* Search for the start of the encoding */
160 while ((line = xmalloc_fgetline(src_stream)) != NULL) { 95 while ((line = xmalloc_fgetline(src_stream)) != NULL) {
161 void (*decode_fn_ptr)(FILE *src, FILE *dst); 96 void FAST_FUNC (*decode_fn_ptr)(FILE *src, FILE *dst, int flags);
162 char *line_ptr; 97 char *line_ptr;
163 FILE *dst_stream; 98 FILE *dst_stream;
164 int mode; 99 int mode;
@@ -189,7 +124,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv)
189 fchmod(fileno(dst_stream), mode & (S_IRWXU | S_IRWXG | S_IRWXO)); 124 fchmod(fileno(dst_stream), mode & (S_IRWXU | S_IRWXG | S_IRWXO));
190 } 125 }
191 free(line); 126 free(line);
192 decode_fn_ptr(src_stream, dst_stream); 127 decode_fn_ptr(src_stream, dst_stream, /*flags:*/ BASE64_FLAG_UU_STOP + BASE64_FLAG_NO_STOP_CHAR);
193 /* fclose_if_not_stdin(src_stream); - redundant */ 128 /* fclose_if_not_stdin(src_stream); - redundant */
194 return EXIT_SUCCESS; 129 return EXIT_SUCCESS;
195 } 130 }
@@ -231,7 +166,7 @@ int base64_main(int argc UNUSED_PARAM, char **argv)
231 *--argv = (char*)"-"; 166 *--argv = (char*)"-";
232 src_stream = xfopen_stdin(argv[0]); 167 src_stream = xfopen_stdin(argv[0]);
233 if (opts) { 168 if (opts) {
234 read_base64(src_stream, stdout); 169 read_base64(src_stream, stdout, /*flags:*/ (char)EOF);
235 } else { 170 } else {
236 enum { 171 enum {
237 SRC_BUF_SIZE = 76/4*3, /* This *MUST* be a multiple of 3 */ 172 SRC_BUF_SIZE = 76/4*3, /* This *MUST* be a multiple of 3 */
diff --git a/include/libbb.h b/include/libbb.h
index d5580b4b0..8d7beffe7 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1505,6 +1505,12 @@ unsigned get_cpu_count(void) FAST_FUNC;
1505extern const char bb_uuenc_tbl_base64[]; 1505extern const char bb_uuenc_tbl_base64[];
1506extern const char bb_uuenc_tbl_std[]; 1506extern const char bb_uuenc_tbl_std[];
1507void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC; 1507void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
1508enum {
1509 BASE64_FLAG_UU_STOP = 0x100,
1510 /* Sign-extends to a value which never matches fgetc result: */
1511 BASE64_FLAG_NO_STOP_CHAR = 0x80,
1512};
1513void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags);
1508 1514
1509typedef struct sha1_ctx_t { 1515typedef struct sha1_ctx_t {
1510 uint32_t hash[8]; /* 5, +3 elements for sha256 */ 1516 uint32_t hash[8]; /* 5, +3 elements for sha256 */
diff --git a/libbb/base64.c b/libbb/base64.c
new file mode 100644
index 000000000..b9d47ae08
--- /dev/null
+++ b/libbb/base64.c
@@ -0,0 +1,78 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
5 * Copyright 2003, Glenn McGrath
6 * Copyright 2010, Denys Vlasenko
7 *
8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
9 */
10#include "libbb.h"
11
12//kbuild:lib-y += base64.o
13
14void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags)
15{
16/* Note that EOF _can_ be passed as exit_char too */
17#define exit_char ((int)(signed char)flags)
18#define uu_style_end (flags & BASE64_FLAG_UUEND)
19
20 int term_count = 0;
21
22 while (1) {
23 unsigned char translated[4];
24 int count = 0;
25
26 /* Process one group of 4 chars */
27 while (count < 4) {
28 char *table_ptr;
29 int ch;
30
31 /* Get next _valid_ character.
32 * bb_uuenc_tbl_base64[] contains this string:
33 * 0 1 2 3 4 5 6
34 * 012345678901234567890123456789012345678901234567890123456789012345
35 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"
36 */
37 do {
38 ch = fgetc(src_stream);
39 if (ch == exit_char && count == 0)
40 return;
41 if (ch == EOF)
42 bb_error_msg_and_die("truncated base64 input");
43 table_ptr = strchr(bb_uuenc_tbl_base64, ch);
44//TODO: add BASE64_FLAG_foo to die on bad char?
45//Note that then we may need to still allow '\r' (for mail processing)
46 } while (!table_ptr);
47
48 /* Convert encoded character to decimal */
49 ch = table_ptr - bb_uuenc_tbl_base64;
50
51 if (ch == 65 /* '\n' */) {
52 /* Terminating "====" line? */
53 if (uu_style_end && term_count == 4)
54 return; /* yes */
55 continue;
56 }
57 /* ch is 64 if char was '=', otherwise 0..63 */
58 translated[count] = ch & 63; /* 64 -> 0 */
59 if (ch == 64) {
60 term_count++;
61 break;
62 }
63 term_count = 0;
64 count++;
65 }
66
67 /* Merge 6 bit chars to 8 bit.
68 * count can be < 4 when we decode the tail:
69 * "eQ==" -> "y", not "y NUL NUL"
70 */
71 if (count > 1)
72 fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
73 if (count > 2)
74 fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
75 if (count > 3)
76 fputc(translated[2] << 6 | translated[3], dst_stream);
77 } /* while (1) */
78}
diff --git a/mailutils/mail.c b/mailutils/mail.c
index 8e52a3efc..89db66166 100644
--- a/mailutils/mail.c
+++ b/mailutils/mail.c
@@ -161,73 +161,6 @@ void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol)
161#undef src_buf 161#undef src_buf
162} 162}
163 163
164void FAST_FUNC decode_base64(FILE *src_stream, FILE *dst_stream)
165{
166 int term_count = 1;
167
168 while (1) {
169 char translated[4];
170 int count = 0;
171
172 while (count < 4) {
173 char *table_ptr;
174 int ch;
175
176 /* Get next _valid_ character.
177 * global vector bb_uuenc_tbl_base64[] contains this string:
178 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"
179 */
180 do {
181 ch = fgetc(src_stream);
182 if (ch == EOF) {
183 bb_error_msg_and_die(bb_msg_read_error);
184 }
185 // - means end of MIME section
186 if ('-' == ch) {
187 // push it back
188 ungetc(ch, src_stream);
189 return;
190 }
191 table_ptr = strchr(bb_uuenc_tbl_base64, ch);
192 } while (table_ptr == NULL);
193
194 /* Convert encoded character to decimal */
195 ch = table_ptr - bb_uuenc_tbl_base64;
196
197 if (*table_ptr == '=') {
198 if (term_count == 0) {
199 translated[count] = '\0';
200 break;
201 }
202 term_count++;
203 } else if (*table_ptr == '\n') {
204 /* Check for terminating line */
205 if (term_count == 5) {
206 return;
207 }
208 term_count = 1;
209 continue;
210 } else {
211 translated[count] = ch;
212 count++;
213 term_count = 0;
214 }
215 }
216
217 /* Merge 6 bit chars to 8 bit */
218 if (count > 1) {
219 fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
220 }
221 if (count > 2) {
222 fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
223 }
224 if (count > 3) {
225 fputc(translated[2] << 6 | translated[3], dst_stream);
226 }
227 }
228}
229
230
231/* 164/*
232 * get username and password from a file descriptor 165 * get username and password from a file descriptor
233 */ 166 */
diff --git a/mailutils/mail.h b/mailutils/mail.h
index bb747c4c5..e0048fbfa 100644
--- a/mailutils/mail.h
+++ b/mailutils/mail.h
@@ -32,4 +32,3 @@ void FAST_FUNC get_cred_or_die(int fd);
32const FAST_FUNC char *command(const char *fmt, const char *param); 32const FAST_FUNC char *command(const char *fmt, const char *param);
33 33
34void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol); 34void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol);
35void FAST_FUNC decode_base64(FILE *src_stream, FILE *dst_stream);
diff --git a/mailutils/mime.c b/mailutils/mime.c
index 44c7d0216..682cf4536 100644
--- a/mailutils/mime.c
+++ b/mailutils/mime.c
@@ -225,7 +225,7 @@ static int parse(const char *boundary, char **argv)
225 // prepare unique string pattern 225 // prepare unique string pattern
226 uniq = xasprintf("%%llu.%u.%s", (unsigned)getpid(), safe_gethostname()); 226 uniq = xasprintf("%%llu.%u.%s", (unsigned)getpid(), safe_gethostname());
227 227
228//bb_info_msg("PARSE[%s]", terminator); 228//bb_info_msg("PARSE[%s]", uniq);
229 229
230 while ((line = xmalloc_fgets_str(stdin, "\r\n\r\n")) != NULL) { 230 while ((line = xmalloc_fgets_str(stdin, "\r\n\r\n")) != NULL) {
231 231
@@ -306,7 +306,7 @@ static int parse(const char *boundary, char **argv)
306 306
307 // dump to fp 307 // dump to fp
308 if (0 == strcasecmp(encoding, "base64")) { 308 if (0 == strcasecmp(encoding, "base64")) {
309 decode_base64(stdin, fp); 309 read_base64(stdin, fp, '-');
310 } else if (0 != strcasecmp(encoding, "7bit") 310 } else if (0 != strcasecmp(encoding, "7bit")
311 && 0 != strcasecmp(encoding, "8bit") 311 && 0 != strcasecmp(encoding, "8bit")
312 ) { 312 ) {