source: npl/mailserver/dspam/dspam-3.10.2/src/base64.c

Last change on this file was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/* $Id: base64.c,v 1.99 2011/06/28 00:13:48 sbajic Exp $ */
2
3/*
4 DSPAM
5 COPYRIGHT (C) 2002-2012 DSPAM PROJECT
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Affero General Public License as
9 published by the Free Software Foundation, either version 3 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20*/
21
22/*
23 * base64.c - base64 encoding/decoding routines
24 *
25 */
26
27#ifdef HAVE_CONFIG_H
28#include <auto-config.h>
29#endif
30
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34
35#include "error.h"
36#include "base64.h"
37
38char *
39base64decode (const char *buf)
40{
41#ifdef VERBOSE
42  LOGDEBUG ("decoding Base64 encoded buffer");
43#endif
44  unsigned char alphabet[64] =
45    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
46  static char first_time = 1,inalphabet[256], decoder[256];
47  int bits, c, char_count;
48  int pos = 0, dpos = 0;
49  char *decoded;
50
51  decoded = malloc ((strlen (buf) * 2) + 2);
52  if (decoded == NULL)
53    return NULL;
54  decoded[0] = 0;
55
56  if(first_time) {
57    int i;
58    for (i = (sizeof alphabet) - 1; i >= 0; i--)
59    {
60      inalphabet[alphabet[i]] = 1;
61      decoder[alphabet[i]] = i;
62    }
63    first_time = 0;
64  }
65  char_count = 0;
66  bits = 0;
67  while (buf[pos] != 0)
68  {
69    c = buf[pos];
70    if (c == '=')
71      break;
72    if (c > 255 || !inalphabet[c])
73    {
74      pos++;
75      continue;
76    }
77    bits += decoder[c];
78    char_count++;
79    if (char_count == 4)
80    {
81      decoded[dpos] = (bits >> 16);
82      decoded[dpos + 1] = ((bits >> 8) & 0xff);
83      decoded[dpos + 2] = (bits & 0xff);
84      decoded[dpos + 3] = 0;
85      dpos += 3;
86      bits = 0;
87      char_count = 0;
88    }
89    else
90    {
91      bits <<= 6;
92    }
93    pos++;
94  }
95  c = buf[pos];
96  if (c == 0)
97  {
98    if (char_count)
99    {
100      LOGDEBUG ("base64 encoding incomplete: at least %d bits truncated",
101                ((4 - char_count) * 6));
102    }
103  }
104  else
105  {                             /* c == '=' */
106    switch (char_count)
107    {
108    case 1:
109      LOGDEBUG ("base64 encoding incomplete: at least 2 bits missing");
110      break;
111    case 2:
112      decoded[dpos] = (bits >> 10);
113      decoded[dpos + 1] = 0;
114      break;
115    case 3:
116      decoded[dpos] = (bits >> 16);
117      decoded[dpos + 1] = ((bits >> 8) & 0xff);
118      decoded[dpos + 2] = 0;
119      break;
120    }
121  }
122  if (strlen(decoded) > 0 && decoded[strlen(decoded)-1] != '\n')
123    strcat(decoded, "\n");
124  return decoded;
125}
126
127char *
128base64encode (const char *buf)
129{
130#ifdef VERBOSE
131  LOGDEBUG ("encoding buffer to Base64");
132#endif
133  unsigned char alphabet[64] =
134    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
135  int cols, bits, c, char_count;
136  char *out;
137  long rpos = 0, wpos = 0;
138
139  out = malloc (strlen (buf) * 2);
140  if (out == NULL)
141    return NULL;
142
143  out[0] = 0;
144
145  char_count = 0;
146  bits = 0;
147  cols = 0;
148  c = buf[rpos];
149  while (c != 0)
150  {
151    bits += c;
152    char_count++;
153    if (char_count == 3)
154    {
155      out[wpos] = (alphabet[bits >> 18]);
156      out[wpos + 1] = (alphabet[(bits >> 12) & 0x3f]);
157      out[wpos + 2] = (alphabet[(bits >> 6) & 0x3f]);
158      out[wpos + 3] = (alphabet[bits & 0x3f]);
159      wpos += 4;
160      cols += 4;
161      if (cols == 72)
162      {
163        out[wpos] = '\n';
164        wpos++;
165        cols = 0;
166      }
167      out[wpos] = 0;
168      bits = 0;
169      char_count = 0;
170    }
171    else
172    {
173      bits <<= 8;
174    }
175    rpos++;
176    c = buf[rpos];
177  }
178  if (char_count != 0)
179  {
180    bits <<= 16 - (8 * char_count);
181    out[wpos] = (alphabet[bits >> 18]);
182    out[wpos + 1] = (alphabet[(bits >> 12) & 0x3f]);
183    wpos += 2;
184    if (char_count == 1)
185    {
186      out[wpos] = '=';
187      out[wpos + 1] = '=';
188    }
189    else
190    {
191      out[wpos] = (alphabet[(bits >> 6) & 0x3f]);
192      out[wpos + 1] = '=';
193    }
194    wpos += 2;
195    if (cols > 0)
196    {
197      out[wpos] = '\n';
198      wpos++;
199    }
200    out[wpos] = 0;
201  }
202
203  if (out[strlen (out) - 1] != '\n')
204    strcat (out, "\n");
205
206  return out;
207}
Note: See TracBrowser for help on using the repository browser.