1
2
3
4
5
6
7
8
9#include "libbb.h"
10
11
12const char bb_uuenc_tbl_base64[65 + 1] ALIGN1 = {
13 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
14 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
15 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
16 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
17 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
18 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
19 'w', 'x', 'y', 'z', '0', '1', '2', '3',
20 '4', '5', '6', '7', '8', '9', '+', '/',
21 '=' ,
22 '\0'
23};
24
25const char bb_uuenc_tbl_std[65] ALIGN1 = {
26 '`', '!', '"', '#', '$', '%', '&', '\'',
27 '(', ')', '*', '+', ',', '-', '.', '/',
28 '0', '1', '2', '3', '4', '5', '6', '7',
29 '8', '9', ':', ';', '<', '=', '>', '?',
30 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
31 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
32 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
33 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
34 '`'
35};
36
37
38
39
40
41
42
43void FAST_FUNC bb_uuencode(char *p, const void *src, int length, const char *tbl)
44{
45 const unsigned char *s = src;
46
47
48 while (length > 0) {
49 unsigned s1, s2;
50
51
52 s1 = s2 = 0;
53 length -= 3;
54 if (length >= -1) {
55 s1 = s[1];
56 if (length >= 0)
57 s2 = s[2];
58 }
59 *p++ = tbl[s[0] >> 2];
60 *p++ = tbl[((s[0] & 3) << 4) + (s1 >> 4)];
61 *p++ = tbl[((s1 & 0xf) << 2) + (s2 >> 6)];
62 *p++ = tbl[s2 & 0x3f];
63 s += 3;
64 }
65
66 *p = '\0';
67
68 while (length) {
69 *--p = tbl[64];
70 length++;
71 }
72}
73
74
75
76
77
78
79
80
81const char* FAST_FUNC decode_base64(char **pp_dst, const char *src)
82{
83 char *dst = *pp_dst;
84 const char *src_tail;
85
86 while (1) {
87 unsigned char six_bit[4];
88 int count = 0;
89
90
91 src_tail = src;
92 while (count < 4) {
93 char *table_ptr;
94 int ch;
95
96
97
98
99
100
101
102 do {
103 ch = *src;
104 if (ch == '\0') {
105 if (count == 0) {
106
107
108
109
110
111
112 src_tail = src;
113 }
114 goto ret;
115 }
116 src++;
117 table_ptr = strchr(bb_uuenc_tbl_base64, ch);
118
119 } while (!table_ptr);
120
121
122 ch = table_ptr - bb_uuenc_tbl_base64;
123
124
125 if (ch == 64)
126 break;
127 six_bit[count] = ch;
128 count++;
129 }
130
131
132
133
134
135
136
137
138
139
140 if (count > 1)
141 *dst++ = six_bit[0] << 2 | six_bit[1] >> 4;
142 if (count > 2)
143 *dst++ = six_bit[1] << 4 | six_bit[2] >> 2;
144 if (count > 3)
145 *dst++ = six_bit[2] << 6 | six_bit[3];
146
147
148
149
150 }
151 ret:
152 *pp_dst = dst;
153 return src_tail;
154}
155
156
157
158
159
160
161void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags)
162{
163
164#define exit_char ((int)(signed char)flags)
165#define uu_style_end (flags & BASE64_FLAG_UU_STOP)
166
167
168
169
170 enum { BUFFER_SIZE = 64 };
171
172 char in_buf[BUFFER_SIZE + 2];
173 char out_buf[BUFFER_SIZE / 4 * 3 + 2];
174 char *out_tail;
175 const char *in_tail;
176 int term_seen = 0;
177 int in_count = 0;
178
179 while (1) {
180 while (in_count < BUFFER_SIZE) {
181 int ch = fgetc(src_stream);
182 if (ch == exit_char) {
183 if (in_count == 0)
184 return;
185 term_seen = 1;
186 break;
187 }
188 if (ch == EOF) {
189 term_seen = 1;
190 break;
191 }
192
193
194
195
196 if (ch <= ' ')
197 break;
198 in_buf[in_count++] = ch;
199 }
200 in_buf[in_count] = '\0';
201
202
203 if (uu_style_end && strcmp(in_buf, "====") == 0)
204 return;
205
206 out_tail = out_buf;
207 in_tail = decode_base64(&out_tail, in_buf);
208
209 fwrite(out_buf, (out_tail - out_buf), 1, dst_stream);
210
211 if (term_seen) {
212
213 if (*in_tail == '\0')
214 return;
215
216 bb_error_msg_and_die("truncated base64 input");
217 }
218
219
220 in_count = strlen(in_tail);
221 memmove(in_buf, in_tail, in_count);
222 }
223}
224