moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kstars / kstars / indi / base64.c
blobbe3504a6fc2aed4c88d577a02e680b05e0776e82
1 /* This program is free software; you can redistribute it and/or modify it
2 * under the terms of the GNU General Public License as published by the Free
3 * Software Foundation; either version 2 of the License, or (at your option) any
4 * later version.
5 *
6 * This program is distributed in the hope that it will be useful, but WITHOUT
7 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
9 * details.
11 * You should have received a copy of the GNU General Public License along with
12 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
13 * Place - Suite 330, Boston, MA 02111-1307, USA.
15 * Adapted from code written by Eric S. Raymond <esr@snark.thyrsus.com>
17 */
19 /* Pair of functions to convert to/from base64.
20 * Also can be used to build a standalone utility and a loopback test.
21 * see http://www.faqs.org/rfcs/rfc3548.html
24 #include <ctype.h>
25 #include "base64.h"
27 static const char base64digits[] =
28 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
30 #define BAD (-1)
31 static const char base64val[] = {
32 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
33 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
34 BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
35 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,BAD,BAD, BAD,BAD,BAD,BAD,
36 BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
37 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,BAD, BAD,BAD,BAD,BAD,
38 BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
39 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD
41 #define DECODE64(c) (isascii(c) ? base64val[c] : BAD)
43 /* convert inlen raw bytes at in to base64 string (NUL-terminated) at out.
44 * out size should be at least 4*inlen/3 + 4.
45 * return length of out (sans trailing NUL).
47 int
48 to64frombits(unsigned char *out, const unsigned char *in, int inlen)
50 unsigned char *out0 = out;
52 for (; inlen >= 3; inlen -= 3)
54 *out++ = base64digits[in[0] >> 2];
55 *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
56 *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
57 *out++ = base64digits[in[2] & 0x3f];
58 in += 3;
60 if (inlen > 0)
62 unsigned char fragment;
64 *out++ = base64digits[in[0] >> 2];
65 fragment = (in[0] << 4) & 0x30;
66 if (inlen > 1)
67 fragment |= in[1] >> 4;
68 *out++ = base64digits[fragment];
69 *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
70 *out++ = '=';
72 *out = '\0';
74 return (out-out0);
77 /* convert base64 at in to raw bytes out, returning count or <0 on error.
78 * base64 may contain any embedded whitespace.
79 * out should be at least 3/4 the length of in.
81 int
82 from64tobits(char *out, const char *in)
84 int len = 0;
85 register unsigned char digit1, digit2, digit3, digit4;
87 do {
88 do {digit1 = *in++;} while (isspace(digit1));
89 if (DECODE64(digit1) == BAD)
90 return(-1);
91 do {digit2 = *in++;} while (isspace(digit2));
92 if (DECODE64(digit2) == BAD)
93 return(-2);
94 do {digit3 = *in++;} while (isspace(digit3));
95 if (digit3 != '=' && DECODE64(digit3) == BAD)
96 return(-3);
97 do {digit4 = *in++;} while (isspace(digit4));
98 if (digit4 != '=' && DECODE64(digit4) == BAD)
99 return(-4);
100 *out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
101 ++len;
102 if (digit3 != '=')
104 *out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
105 ++len;
106 if (digit4 != '=')
108 *out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);
109 ++len;
112 while (isspace(*in))
113 in++;
114 } while (*in && digit4 != '=');
116 return (len);
119 #ifdef BASE64_PROGRAM
120 /* standalone program that converts to/from base64.
121 * cc -o base64 -DBASE64_PROGRAM base64.c
124 #include <stdio.h>
125 #include <stdlib.h>
126 #include <string.h>
128 static void
129 usage (char *me)
131 fprintf (stderr, "Purpose: convert stdin to/from base64 on stdout\n");
132 fprintf (stderr, "Usage: %s {-t,-f}\n", me);
133 exit (1);
137 main (int ac, char *av[])
139 int to64 = 1;
141 /* decide whether to or from base64 */
142 if (ac == 2 && strcmp (av[1], "-f") == 0)
143 to64 = 0;
144 else if (ac != 1 && (ac != 2 || strcmp (av[1], "-t")))
145 usage (av[0]);
147 if (to64) {
148 unsigned char *rawin, *b64;
149 int i, n, nrawin, nb64;
151 /* read raw on stdin until EOF */
152 rawin = malloc(4096);
153 nrawin = 0;
154 while ((n = fread (rawin+nrawin, 1, 4096, stdin)) > 0)
155 rawin = realloc (rawin, (nrawin+=n)+4096);
157 /* convert to base64 */
158 b64 = malloc (4*nrawin/3+4);
159 nb64 = to64frombits(b64, rawin, nrawin);
161 /* pretty print */
162 for (i = 0; i < nb64; i += 72)
163 printf ("%.*s\n", 72, b64+i);
164 } else {
165 unsigned char *raw, *b64;
166 int n, nraw, nb64;
168 /* read base64 on stdin until EOF */
169 b64 = malloc(4096);
170 nb64 = 0;
171 while ((n = fread (b64+nb64, 1, 4096, stdin)) > 0)
172 b64 = realloc (b64, (nb64+=n)+4096);
173 b64[nb64] = '\0';
175 /* convert to raw */
176 raw = malloc (3*nb64/4);
177 nraw = from64tobits(raw, b64);
178 if (nraw < 0) {
179 fprintf (stderr, "base64 conversion error: %d\n", nraw);
180 return (1);
183 /* write */
184 fwrite (raw, 1, nraw, stdout);
187 return (0);
190 #endif
192 #ifdef LOOPBACK_TEST
193 /* standalone test that reads binary on stdin, converts to base64 and back,
194 * then compares. exit 0 if compares the same else 1
197 #include <stdio.h>
198 #include <stdlib.h>
199 #include <string.h>
202 main (int ac, char *av[])
204 unsigned char *rawin, *b64, *rawback;
205 int n, nrawin, nrawback, nb64;
207 /* read raw on stdin until EOF */
208 rawin = malloc(4096);
209 nrawin = 0;
210 while ((n = fread (rawin+nrawin, 1, 4096, stdin)) > 0)
211 rawin = realloc (rawin, (nrawin+=n)+4096);
213 /* convert to base64 */
214 b64 = malloc (4*nrawin*3 + 4);
215 nb64 = to64frombits(b64, rawin, nrawin);
217 /* convert back to raw */
218 rawback = malloc (3*nb64/4);
219 nrawback = from64tobits(rawback, b64);
220 if (nrawback < 0) {
221 fprintf (stderr, "base64 error: %d\n", nrawback);
222 return(1);
224 if (nrawback != nrawin) {
225 fprintf (stderr, "base64 back length %d != %d\n", nrawback, nrawin);
226 return(1);
229 /* compare */
230 if (memcmp (rawback, rawin, nrawin)) {
231 fprintf (stderr, "compare error\n");
232 return (1);
235 /* success */
236 return (0);
238 #endif
239 /* For RCS Only -- Do Not Edit */
240 static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile$ $Date$ $Revision$ $Name: $"};