1 /* vi: set sw=4 ts=4: */
5 * Copyright 2003, Glenn McGrath
6 * Copyright 2010, Denys Vlasenko
8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
12 //kbuild:lib-y += base64.o
14 void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags)
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)
23 unsigned char translated[4];
26 /* Process one group of 4 chars */
31 /* Get next _valid_ character.
32 * bb_uuenc_tbl_base64[] contains this string:
34 * 012345678901234567890123456789012345678901234567890123456789012345
35 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"
38 ch = fgetc(src_stream);
39 if (ch == exit_char && count == 0)
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)
48 /* Convert encoded character to decimal */
49 ch = table_ptr - bb_uuenc_tbl_base64;
51 if (ch == 65 /* '\n' */) {
52 /* Terminating "====" line? */
53 if (uu_style_end && term_count == 4)
57 /* ch is 64 if char was '=', otherwise 0..63 */
58 translated[count] = ch & 63; /* 64 -> 0 */
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"
72 fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
74 fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
76 fputc(translated[2] << 6 | translated[3], dst_stream);