base64.c - rohrpost - A commandline mail client to change the world as we see it.
(HTM) git clone git://r-36.net/rohrpost
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
base64.c (2214B)
---
1 /*
2 * Copy me if you can.
3 * by 20h
4 */
5
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <strings.h>
10
11 #include "ind.h"
12
13 char be[] =
14 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
15
16 int
17 readnwstr(char *buf, char *str, int *p, int max, int l)
18 {
19 int i, j;
20
21 for (i = 0; *p < max && i < l; (*p)++) {
22 for (j = 0; j < strlen(be); j++) {
23 if (str[*p] == be[j]) {
24 buf[i++] = str[*p];
25 break;
26 }
27 }
28 }
29
30 if (i < l)
31 return 1;
32 return 0;
33 }
34
35 char *
36 b64enc(char *str, int l)
37 {
38 char *ret;
39 int p, po, left;
40
41 po = 0;
42 p = 0;
43
44 ret = mallocz(5, 0);
45 for (; p < l; p += 3, po += 4) {
46 ret = reallocz(ret, po + 5, 0);
47
48 ret[po] = be[(str[p] & 0xFC) >> 2];
49 ret[po+1] = be[(str[p] & 0x03) << 4 \
50 | (str[p+1] & 0xF0) >> 4];
51 ret[po+2] = be[(str[p+1] & 0x0F) << 2 \
52 | (str[p+2] & 0xC0) >> 6];
53 ret[po+3] = be[str[p+2] & 0x3F];
54 }
55 left = l - p + 3;
56 po -= 4;
57 switch (left) {
58 case 1:
59 ret[po+2] = '=';
60 case 2:
61 ret[po+3] = '=';
62 default:
63 break;
64 }
65 ret[po+4] = '\0';
66
67 return ret;
68 }
69
70 char *
71 b64dec(char *istr, int *len)
72 {
73 char *ret, str[5];
74 int p, po, l, uglyline;
75 char bd[256];
76
77 memset(bd, 0x80, 256);
78 /* Without »=«. */
79 for (p = 0; p < strlen(be)-1; p++)
80 bd[(int)be[p]] = p;
81 bd['='] = 0;
82
83 p = 0;
84 po = 0;
85 ret = NULL;
86
87 /*
88 * If there is something prepended to the base64 block, take it as-is.
89 */
90 for (uglyline = 1, l = 0; uglyline == 1; l = p) {
91 uglyline = 0;
92 for (; istr[l] != '\n' && istr[l]; l++) {
93 if (istr[l] == ' ')
94 uglyline = 1;
95 }
96 /* Take care of empty lines. */
97 if ((l - p) == 1 && istr[l-1] == '\r')
98 uglyline = 1;
99 if ((l - p) == 0)
100 uglyline = 1;
101 if (uglyline)
102 po = p = l + 1;
103 }
104 if (p > 0) {
105 ret = reallocz(ret, l, 0);
106 memmove(ret, istr, p+1);
107 }
108
109
110 for (; !readnwstr(str, istr, &p, *len, 4); po += 3) {
111 ret = reallocz(ret, po + 4, 0);
112
113 ret[po] = bd[(int)str[0]] << 2 | bd[(int)str[1]] >> 4;
114 ret[po+1] = bd[(int)str[1]] << 4 | bd[(int)str[2]] >> 2;
115 ret[po+2] = bd[(int)str[2]] << 6 | bd[(int)str[3]];
116 }
117 if (str[3] == '=')
118 po--;
119 if (str[2] == '=')
120 po--;
121 ret[po] = '\0';
122 *len = po;
123
124 return ret;
125 }
126
127 int
128 b64len(int len)
129 {
130 return (len / 3) * 4 + (len % 3 > 0)? 4 : 0;
131 }
132