diff options
-rw-r--r-- | base64.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/base64.c b/base64.c new file mode 100644 index 00000000..918af9d5 --- /dev/null +++ b/base64.c @@ -0,0 +1,92 @@ +/* from imtest.c -- IMAP/IMSP test client + * Cyrus IMAPd 1.5.2 <URL:ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-imapd-v1.5.2.tar.gz> + * + * Copyright 1996, Carnegie Mellon University. All Rights Reserved. + * + * This software is made available for academic and research + * purposes only. No commercial license is hereby granted. + * Copying and other reproduction is authorized only for research, + * education, and other non-commercial purposes. No warranties, + * either expressed or implied, are made regarding the operation, + * use, or results of the software. Such a release does not permit + * use of the code for commercial purposes or benefits by anyone + * without specific, additional permission by the owner of the code. + * + * Author: Chris Newman <chrisn+@cmu.edu> + * Start Date: 2/16/93 + */ + +/* base64 tables + */ +static char basis_64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static char index_64[128] = { + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, + -1, 0, 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,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +}; +#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) + +void to64(out, in, inlen) + unsigned char *out, *in; + int inlen; +{ + unsigned char oval; + + while (inlen >= 3) { + *out++ = basis_64[in[0] >> 2]; + *out++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)]; + *out++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; + *out++ = basis_64[in[2] & 0x3f]; + in += 3; + inlen -= 3; + } + if (inlen > 0) { + *out++ = basis_64[in[0] >> 2]; + oval = (in[0] << 4) & 0x30; + if (inlen > 1) oval |= in[1] >> 4; + *out++ = basis_64[oval]; + *out++ = (inlen < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c]; + *out++ = '='; + } + *out = '\0'; +} + +int from64(out, in) + char *out, *in; +{ + int len = 0; + int c1, c2, c3, c4; + + if (in[0] == '+' && in[1] == ' ') in += 2; + if (*in == '\r') return (0); + do { + c1 = in[0]; + if (CHAR64(c1) == -1) return (-1); + c2 = in[1]; + if (CHAR64(c2) == -1) return (-1); + c3 = in[2]; + if (c3 != '=' && CHAR64(c3) == -1) return (-1); + c4 = in[3]; + if (c4 != '=' && CHAR64(c4) == -1) return (-1); + in += 4; + *out++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4); + ++len; + if (c3 != '=') { + *out++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2); + ++len; + if (c4 != '=') { + *out++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4); + ++len; + } + } + } while (*in != '\r' && c4 != '='); + + return (len); +} + |