]> Pileus Git - ~andy/fetchmail/blob - base64.c
Initial revision
[~andy/fetchmail] / base64.c
1 /* from imtest.c -- IMAP/IMSP test client
2  * Cyrus IMAPd 1.5.2 <URL:ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-imapd-v1.5.2.tar.gz>
3  *
4  * Copyright 1996, Carnegie Mellon University.  All Rights Reserved.
5  * 
6  * This software is made available for academic and research
7  * purposes only.  No commercial license is hereby granted.
8  * Copying and other reproduction is authorized only for research,
9  * education, and other non-commercial purposes.  No warranties,
10  * either expressed or implied, are made regarding the operation,
11  * use, or results of the software.  Such a release does not permit
12  * use of the code for commercial purposes or benefits by anyone
13  * without specific, additional permission by the owner of the code.
14  *
15  * Author: Chris Newman <chrisn+@cmu.edu>
16  * Start Date: 2/16/93
17  */
18
19 /* base64 tables
20  */
21 static char basis_64[] =
22    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
23 static char index_64[128] = {
24     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
25     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
26     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
27     52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
28     -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
29     15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
30     -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
31     41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
32 };
33 #define CHAR64(c)  (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
34
35 void to64(out, in, inlen)
36     unsigned char *out, *in;
37     int inlen;
38 {
39     unsigned char oval;
40     
41     while (inlen >= 3) {
42         *out++ = basis_64[in[0] >> 2];
43         *out++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)];
44         *out++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
45         *out++ = basis_64[in[2] & 0x3f];
46         in += 3;
47         inlen -= 3;
48     }
49     if (inlen > 0) {
50         *out++ = basis_64[in[0] >> 2];
51         oval = (in[0] << 4) & 0x30;
52         if (inlen > 1) oval |= in[1] >> 4;
53         *out++ = basis_64[oval];
54         *out++ = (inlen < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c];
55         *out++ = '=';
56     }
57     *out = '\0';
58 }
59
60 int from64(out, in)
61     char *out, *in;
62 {
63     int len = 0;
64     int c1, c2, c3, c4;
65
66     if (in[0] == '+' && in[1] == ' ') in += 2;
67     if (*in == '\r') return (0);
68     do {
69         c1 = in[0];
70         if (CHAR64(c1) == -1) return (-1);
71         c2 = in[1];
72         if (CHAR64(c2) == -1) return (-1);
73         c3 = in[2];
74         if (c3 != '=' && CHAR64(c3) == -1) return (-1); 
75         c4 = in[3];
76         if (c4 != '=' && CHAR64(c4) == -1) return (-1);
77         in += 4;
78         *out++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4);
79         ++len;
80         if (c3 != '=') {
81             *out++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2);
82             ++len;
83             if (c4 != '=') {
84                 *out++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4);
85                 ++len;
86             }
87         }
88     } while (*in != '\r' && c4 != '=');
89
90     return (len);
91 }
92