1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

NNTP: Add support for handling RFC2047 encoded words

Code adapted from git's builtin-mailinfo.c file.
This commit is contained in:
Jonas Fonseca 2007-09-11 16:59:56 +02:00
parent 78eae9cbf3
commit 0b0222d64f

View File

@ -199,6 +199,128 @@ get_nntp_title(struct connection *conn)
return title.source; return title.source;
} }
static void
decode_q_segment(struct string *str, unsigned char *in, unsigned char *end)
{
int c;
while ((c = *in++) != 0 && (in <= end)) {
if (c == '=') {
int d = *in++;
if (d == '\n' || !d)
break; /* drop trailing newline */
d = (unhx(d) << 4) | unhx(*in++);
add_format_to_string(str, "&#%d;", d);
continue;
}
if (c == '_') /* rfc2047 4.2 (2) */
c = 0x20;
add_char_to_string(str, c);
}
}
static void
decode_b_segment(struct string *str, unsigned char *in, unsigned char *end)
{
/* Decode in..ep, possibly in-place to ot */
int c, pos = 0, acc = 0;
while ((c = *in++) != 0 && (in <= end)) {
if (c == '+')
c = 62;
else if (c == '/')
c = 63;
else if ('A' <= c && c <= 'Z')
c -= 'A';
else if ('a' <= c && c <= 'z')
c -= 'a' - 26;
else if ('0' <= c && c <= '9')
c -= '0' - 52;
else if (c == '=') {
/* padding is almost like (c == 0), except we do
* not output NUL resulting only from it;
* for now we just trust the data.
*/
c = 0;
}
else
continue; /* garbage */
switch (pos++) {
case 0:
acc = (c << 2);
break;
case 1:
add_format_to_string(str, "&#%d;", (acc | (c >> 4)));
acc = (c & 15) << 4;
break;
case 2:
add_format_to_string(str, "&#%d;", (acc | (c >> 2)));
acc = (c & 3) << 6;
break;
case 3:
add_format_to_string(str, "&#%d;", (acc | c));
acc = pos = 0;
break;
}
}
}
static void
add_header_to_string(struct string *str, unsigned char *header)
{
unsigned char *end;
int rfc2047 = 0;
while ((end = strstr(header, "=?")) != NULL) {
int encoding;
unsigned char charset_q[256];
unsigned char *cp, *sp;
rfc2047 = 1;
if (header != end) {
add_html_to_string(str, header, end - header);
header = end;
}
/* E.g.
* ep : "=?iso-2022-jp?B?GyR...?= foo"
* ep : "=?ISO-8859-1?Q?Foo=FCbar?= baz"
*/
end += 2;
cp = strchr(end, '?');
if (!cp)
break;
for (sp = end; sp < cp; sp++)
charset_q[sp - end] = tolower(*sp);
charset_q[cp - end] = 0;
encoding = tolower(cp[1]);
if (!encoding || cp[2] != '?')
break;
cp += 3;
end = strstr(cp + 3, "?=");
if (!end)
break;
if (encoding == 'b')
decode_b_segment(str, cp, end);
else if (encoding == 'q')
decode_q_segment(str, cp, end);
else
break;
header = end + 2;
}
add_html_to_string(str, header, strlen(header));
}
static void static void
add_nntp_html_start(struct string *html, struct connection *conn) add_nntp_html_start(struct string *html, struct connection *conn)
{ {
@ -236,7 +358,7 @@ add_nntp_html_start(struct string *html, struct connection *conn)
} }
add_format_to_string(html, "<b>%s</b>: ", entry); add_format_to_string(html, "<b>%s</b>: ", entry);
add_html_to_string(html, value, strlen(value)); add_header_to_string(html, value);
add_char_to_string(html, '\n'); add_char_to_string(html, '\n');
mem_free(value); mem_free(value);
mem_free(entry); mem_free(entry);