Init mime struct
[rmail.git] / src / utils / rfc2047.c
blobe9b19abf1e0319656c662948748ba6d46645d461
2 #include <stdio.h>
3 #include <string.h>
5 #include "string_utils.h"
7 /*
8 * Index_hex and Index_64 imported from Mutt:handler.c
9 * decode_quotedprintable() and decode_base64() as well
11 static const int index_hex[128] = {
12 /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
13 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
14 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
15 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
16 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
17 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
18 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
19 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
20 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
23 static const int index_64[128] = {
24 /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
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, -1, -1, -1, -1, -1,
27 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
28 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
29 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
30 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
31 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
32 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
35 #define HEX_VAL(c) index_hex[(unsigned int)(c)]
36 #define BASE64_VAL(c) index_64[(unsigned int)(c)]
38 /* Decode a string from base64 */
39 void rfc2047_decode_base64(char *dest, const char *src, size_t n)
41 const char *end;
43 int c;
44 int b = 0;
45 int k = 0;
47 if (!dest || !src || (n == 0)) {
48 return;
51 end = src + n;
53 for ( ; src < end; src++) {
54 if (*src == '=')
55 break;
56 if ((*src & 0x80) || (c = BASE64_VAL(*src)) == -1)
57 continue;
58 if (k + 6 >= 8) {
59 k -= 2;
60 *(dest++) = b | (c >> k);
61 b = c << (8 - k);
62 } else {
63 b |= c << (k + 2);
64 k += 6;
66 *dest = '\0';
70 void rfc2047_decode_quoted_printable(char *dest, const char *src, size_t n)
72 const char *end;
74 if (!dest || !src || (n == 0)) {
75 return;
78 end = src + n;
80 while (src < end) {
81 if (*src == '_') {
82 *dest = ' ';
83 } else if ((*src == '=') && (src + 2 < end) &&
84 (!(*(src + 1) & 0x80) && HEX_VAL(*(src + 1)) != -1) &&
85 (!(*(src + 2) & 0x80) && HEX_VAL(*(src + 2)) != -1))
87 *dest = (HEX_VAL(*(src + 1)) << 4) |
88 HEX_VAL(*(src + 2));
89 src += 2;
90 } else {
91 *dest = *src;
93 src++;
94 dest++;
97 *dest = '\0';
101 * encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
103 void rfc2047_decode_word(char *dest, const char *src, size_t n)
105 char *start = NULL;
106 char *end = NULL;
108 char *encoding;
109 char *charset;
111 start = strstr(src, "=?");
112 end = strstr(src, "?=");
114 if (!start || !end) {
115 strncpy(dest, src, n);
116 return;
119 /* Adjust pointers */
120 start += 2;
122 charset = start;
123 #if 0
124 printf("charset @%d\n", charset - src);
125 #endif
127 encoding = strchr(start, '?');
128 if (encoding == end) {
129 /* Something wrong */
131 encoding++;
133 #if 0
134 printf("encoding @%d\n", encoding - src);
135 #endif
137 start = encoding + 2;
139 if (*encoding == 'Q') {
140 rfc2047_decode_quoted_printable(dest, start, end - start);
141 } else if (*encoding == 'B') {
142 rfc2047_decode_base64(dest, start, end - start);
143 } else {
144 fprintf(stderr, "Unkonwn encoding '%c'\n", *encoding);