nicer formatting
[tridge/junkcode.git] / ubase64.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <errno.h>
4 #include <stdlib.h>
5
6
7 /***************************************************************************
8 decode a base64 string in-place - simple and slow algorithm
9   ***************************************************************************/
10 static int base64_decode(char *s)
11 {
12         char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
13         int bit_offset, byte_offset, idx, i, n;
14         unsigned char *d = (unsigned char *)s;
15         char *p;
16
17         n=i=0;
18
19         while (*s && ((*s == '\n') || (p=strchr(b64,*s)))) {
20                 if (*s == '\n') {
21                         s++;
22                         continue;
23                 }
24                 idx = (int)(p - b64);
25                 byte_offset = (i*6)/8;
26                 bit_offset = (i*6)%8;
27                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
28                 if (bit_offset < 3) {
29                         d[byte_offset] |= (idx << (2-bit_offset));
30                         n = byte_offset+1;
31                 } else {
32                         d[byte_offset] |= (idx >> (bit_offset-2));
33                         d[byte_offset+1] = 0;
34                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
35                         n = byte_offset+2;
36                 }
37                 s++; i++;
38         }
39         /* null terminate */
40         d[n] = 0;
41         return n;
42 }
43
44
45 static int load_stdin(char **s)
46 {
47         char buf[1024];
48         int length = 0;
49
50         *s = NULL;
51
52         while (1) {
53                 int n = read(0, buf, sizeof(buf));
54                 if (n == -1 && errno == EINTR) continue;
55                 if (n <= 0) break;
56
57                 (*s) = realloc((*s), length + n + 1);
58                 if (!(*s)) return 0;
59
60                 memcpy((*s)+length, buf, n);
61                 length += n;
62         }
63
64         (*s)[length] = 0;
65         
66         return length;
67 }
68
69 int main(int argc, char *argv[])
70 {
71         char *s;
72         int n;
73
74         n = load_stdin(&s);
75
76         n = base64_decode(s);
77         write(1, s, n);
78         return 0;
79 }