?revision_form?Rev ?revision_input??revision_submit??revision_endform?
Blame |
Last modification |
View Log
| RSS feed
This patch adds support for UTF-8 and modified UTF-7. Functions are in
the new utf8.c. The patch adds calls to utf8_to_imaputf7() or
utf8_from_imaputf7() wherever a folder name is handled in the code. In
addition, it changes prayer to use UTF-8 in all HTML output as well as
in composition of messages.
Index: prayer-1.0.18/prayer/Makefile
===================================================================
--- prayer-1.0.18.orig/prayer/Makefile 2007-03-10 19:39:29.563948453 +0100
+++ prayer-1.0.18/prayer/Makefile 2007-03-10 19:39:30.294042473 +0100
@@ -127,7 +127,7 @@ SESSION_SUPPORT_OBJS = \
abook.o lookup.o role.o dictionary.o \
options.o rfc1522.o banner.o favourite.o wrap.o portlist.o \
account.o account_msshell.o account_sieve.o account_support.o \
- sieve.o filter.o checksum.o
+ sieve.o filter.o checksum.o utf8.o
ifeq ($(strip $(SESSION_NEEDS_DB)), true)
SESSION_SUPPORT_OBJS += mydb_db3.o
Index: prayer-1.0.18/prayer/cmd_change.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_change.c 2007-03-10 19:38:53.659325192 +0100
+++ prayer-1.0.18/prayer/cmd_change.c 2007-03-10 19:39:30.344048912 +0100
@@ -16,7 +16,7 @@ void cmd_change(struct session *session)
if (request->method == POST) {
request_decode_post(request);
- if (!(name = assoc_lookup(request->form, "folder"))) {
+ if (!(name = utf8_to_imaputf7(request->pool, assoc_lookup(request->form, "folder")))) {
session_redirect(session, request, "error");
return;
}
@@ -30,7 +30,8 @@ void cmd_change(struct session *session)
}
if (!session_streams_change(session, name)) {
- session_message(session, "Unable to switch to folder: %s", name);
+ session_message(session, "Unable to switch to folder: %s",
+ utf8_from_imaputf7(request->pool, name));
session_redirect(session, request, "restart");
return;
}
@@ -47,7 +48,7 @@ void cmd_change(struct session *session)
}
session_message(session, "Switched to mailbox: %s",
- session->foldername);
+ utf8_from_imaputf7(request->pool, session->foldername));
session_log(session, "[cmd_change] Switched to mailbox: %s",
session->foldername);
Index: prayer-1.0.18/prayer/cmd_compose.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_compose.c 2007-03-10 19:38:53.719332917 +0100
+++ prayer-1.0.18/prayer/cmd_compose.c 2007-03-10 19:39:30.384054064 +0100
@@ -244,7 +244,7 @@ static BOOL cmd_compose_generate_postpon
strlen(string), string, NIL);
string =
- string_prune(request->pool, string, config->list_addr_maxlen);
+ utf8_prune(request->pool, string, config->list_addr_maxlen);
bputs(b, "<td>" CRLF);
html_quote_string(b, string);
@@ -267,7 +267,7 @@ static BOOL cmd_compose_generate_postpon
rfc1522_decode(pool_alloc(request->pool, strlen(string)),
strlen(string), string, NIL);
- string = string_prune(request->pool, string,
+ string = utf8_prune(request->pool, string,
config->list_subject_maxlen);
} else
string = "(No subject)";
Index: prayer-1.0.18/prayer/cmd_copy.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_copy.c 2007-03-10 19:38:53.769339356 +0100
+++ prayer-1.0.18/prayer/cmd_copy.c 2007-03-10 19:39:30.404056640 +0100
@@ -95,7 +95,7 @@ generate_directory_line(struct session *
html_session_bprintf(session, b,
"<td><a href=\"", "\">" CRLF, "copy?cwd=%s",
name);
- html_quote_string(b, dir);
+ html_quote_string(b, utf8_from_imaputf7(pool, dir));
bprintf(b, "</a></td>" CRLF);
bputs(b, "</tr>" CRLF);
@@ -127,7 +127,7 @@ generate_favourite_folder_line(struct se
html_session_bprintf(session, b,
"<td><a href=\"", "\">" CRLF, "copy_msg/%s",
name);
- html_quote_string(b, folder);
+ html_quote_string(b, utf8_from_imaputf7(pool, folder));
bprintf(b, "</a></td>" CRLF);
bputs(b, "</tr>" CRLF);
@@ -159,7 +159,7 @@ generate_folder_line(struct session *ses
html_session_bprintf(session, b,
"<td><a href=\"", "\">" CRLF, "copy_msg/%s",
name);
- html_quote_string(b, folder);
+ html_quote_string(b, utf8_from_imaputf7(pool, folder));
bprintf(b, "</a></td>" CRLF);
bprintf(b, "</tr>" CRLF);
@@ -209,8 +209,8 @@ html_folderlist(struct session *session,
bputs(b, "<tr>");
bputs(b, "<td>");
bputs(b, "<table><tr><td>" CRLF);
- html_form_field(b, "Directory", "cwd", session->cwd, 32);
- html_form_field(b, "Filter", "filter", session->dir_filter, 12);
+ html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
+ html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
html_form_submit(b, "submit", "Apply");
bputs(b, "</td></tr></table>" CRLF);
bputs(b, "<td align=\"right\"><table><tr><td>" CRLF);
Index: prayer-1.0.18/prayer/cmd_copy_msg.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_copy_msg.c 2007-03-10 19:38:53.829347082 +0100
+++ prayer-1.0.18/prayer/cmd_copy_msg.c 2007-03-10 19:39:30.484066944 +0100
@@ -125,12 +125,13 @@ void cmd_copy_msg(struct session *sessio
/* Keep current message */
if (count > 1) {
session_message(session, "Copied %lu messages to %s", count,
- mailbox);
+ utf8_from_imaputf7(request->pool, mailbox));
session_log(session,
"[cmd_copy_msg] Copied %lu messages to %s", count,
mailbox);
} else if (count == 1) {
- session_message(session, "Copied 1 message to %s", mailbox);
+ session_message(session, "Copied 1 message to %s",
+ utf8_from_imaputf7(request->pool, mailbox));
session_log(session, "[cmd_copy_msg] Copied 1 message to %s",
mailbox);
} else {
@@ -152,9 +153,8 @@ void cmd_copy_msg(struct session *sessio
next = msgmap_value(zm, zm_offset + 1);
else {
/* No next message */
- session_message(session,
- "Copied message %lu to \"%s\", no more messages",
- msgno, mailbox);
+ session_message(session, "Copied message %lu to \"%s\", no more messages",
+ msgno, utf8_from_imaputf7(request->pool, mailbox));
session_log(session, "[cmd_copy_msg] Copied message %lu to %s",
msgno, mailbox);
session->current = msgno;
@@ -162,9 +162,8 @@ void cmd_copy_msg(struct session *sessio
return;
}
- session_message(session,
- "Copied message %lu to \"%s\", displaying %lu out of %lu",
- msgno, mailbox, next, zm->nmsgs);
+ session_message(session, "Copied message %lu to \"%s\", displaying %lu out of %lu",
+ msgno, utf8_from_imaputf7(request->pool, mailbox), next, zm->nmsgs);
session_log(session, "[cmd_copy_msg] Copied message %lu to %s",
msgno, mailbox);
Index: prayer-1.0.18/prayer/cmd_create.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_create.c 2007-03-10 19:38:53.919358672 +0100
+++ prayer-1.0.18/prayer/cmd_create.c 2007-03-10 19:39:30.554075959 +0100
@@ -21,7 +21,8 @@ void cmd_create(struct session *session)
request_decode_get(request);
- if ((mailbox = assoc_lookup(request->form, "name")) == NIL) {
+ if ((mailbox = utf8_to_imaputf7(request->pool,
+ assoc_lookup(request->form, "name"))) == NIL) {
session_redirect(session, request, "error");
return;
}
@@ -58,12 +59,13 @@ void cmd_create(struct session *session)
if (ml_have_error()) {
session_message(session,
"Failed to create directory: %s - %s",
- path, ml_errmsg());
+ utf8_from_imaputf7(request->pool, path), ml_errmsg());
session_log(session,
"[cmd_create] Failed to create directory: %s",
path);
} else {
- session_message(session, "Created directory: %s", path);
+ session_message(session, "Created directory: %s",
+ utf8_from_imaputf7(request->pool, path));
session_log(session,
"[cmd_create] Created directory: %s", path);
dircache_add(session->dircache, path, T);
@@ -72,12 +74,13 @@ void cmd_create(struct session *session)
if (ml_have_error()) {
session_message(session,
"Failed to create mailbox: %s - %s",
- path, ml_errmsg());
+ utf8_from_imaputf7(request->pool, path), ml_errmsg());
session_log(session,
"[cmd_create] Failed to create mailbox: %s",
path);
} else {
- session_message(session, "Created mailbox: %s", path);
+ session_message(session, "Created mailbox: %s",
+ utf8_from_imaputf7(request->pool, path));
session_log(session, "[cmd_create] Created mailbox: %s",
path);
dircache_add(session->dircache, path, NIL);
Index: prayer-1.0.18/prayer/cmd_dir_check.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_dir_check.c 2007-03-10 19:38:53.979366397 +0100
+++ prayer-1.0.18/prayer/cmd_dir_check.c 2007-03-10 19:39:30.584079823 +0100
@@ -43,7 +43,7 @@ void cmd_dir_check(struct session *sessi
session_message(session,
"Refreshed directory cache for directory \"%s\" at %s",
- session->cwd, current_time());
+ utf8_from_imaputf7(request->pool, session->cwd), current_time());
dircache_invalidate(session, session->cwd);
if (request->argc >= 2)
Index: prayer-1.0.18/prayer/cmd_display.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_display.c 2007-03-10 19:38:54.049375411 +0100
+++ prayer-1.0.18/prayer/cmd_display.c 2007-03-10 19:39:30.644087551 +0100
@@ -567,9 +567,11 @@ show_textpart(struct session *session, M
struct request *request = session->request;
struct buffer *b = request->write_buffer;
char *init_msg, *decode_msg;
+ char *charset = "ISO-8859-1";
unsigned long len;
BODY *body = NIL;
BOOL show_html = NIL;
+ PARAMETER *parameter;
if (!(body = ml_body(session, stream, msgno, section)))
return(NIL);
@@ -580,6 +582,13 @@ show_textpart(struct session *session, M
return(NIL);
}
+ for (parameter = body->parameter; parameter; parameter = parameter->next) {
+ if (strcasecmp(parameter->attribute, "charset") == 0) {
+ charset = parameter->value;
+ break;
+ }
+ }
+
if (!(init_msg = ml_fetchbody(session, stream, msgno, section, &len)))
return(NIL);
@@ -637,10 +646,10 @@ show_textpart(struct session *session, M
if (show_html) {
if (decode_msg == init_msg)
decode_msg = strdup(init_msg);
- html_secure(session, b, decode_msg);
+ html_secure(session, b, utf8_from_string(request->pool, charset, decode_msg, len));
} else {
bprintf(b, "<pre>" CRLF);
- wrap_line_html(session, b, decode_msg, 80);
+ wrap_line_html(session, b, utf8_from_string(request->pool, charset, decode_msg, len), 80);
bprintf(b, "</pre>" CRLF);
}
Index: prayer-1.0.18/prayer/cmd_favourites.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_favourites.c 2007-03-10 19:38:54.109383138 +0100
+++ prayer-1.0.18/prayer/cmd_favourites.c 2007-03-10 19:39:30.664090126 +0100
@@ -104,7 +104,7 @@ generate_directory_line(struct session *
html_session_bprintf(session, b, "<a href=\"", "\">" CRLF,
"favourites?cwd=%s", name);
- html_quote_string(b, dir);
+ html_quote_string(b, utf8_from_imaputf7(pool, dir));
bprintf(b, "</a></td>" CRLF);
bputs(b, "<td> </td>" CRLF);
bputs(b, "<td> </td>" CRLF);
@@ -134,7 +134,7 @@ generate_favourite_folder_line(struct se
bputs(b, "</td>" CRLF);
bputs(b, "<td nowrap>" CRLF);
- html_quote_string(b, folder);
+ html_quote_string(b, utf8_from_imaputf7(pool, folder));
bputs(b, "</td>" CRLF);
html_textlink_mailbox_table(session, b, "unsubscribe", name,
@@ -170,7 +170,7 @@ generate_folder_line(struct session *ses
bputs(b, "</td>" CRLF);
bprintf(b, "<td nowrap>" CRLF);
- html_quote_string(b, folder);
+ html_quote_string(b, utf8_from_imaputf7(pool, folder));
bprintf(b, "</td>" CRLF);
html_textlink_mailbox_table(session, b, "subscribe", name,
@@ -208,8 +208,8 @@ html_folderlist(struct session *session,
bputs(b, "<tr>");
bputs(b, "<td>");
bputs(b, "<table><tr><td>" CRLF);
- html_form_field(b, "Directory", "cwd", session->cwd, 32);
- html_form_field(b, "Filter", "filter", session->dir_filter, 12);
+ html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
+ html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
html_form_submit(b, "submit", "Apply");
bputs(b, "</td></tr></table>" CRLF);
bputs(b, "</td>" CRLF);
Index: prayer-1.0.18/prayer/cmd_filter_select.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_filter_select.c 2007-03-10 19:38:54.159389577 +0100
+++ prayer-1.0.18/prayer/cmd_filter_select.c 2007-03-10 19:39:30.694093991 +0100
@@ -68,7 +68,7 @@ generate_directory_line(struct session *
html_session_bprintf(session, b, "<td><a href=\"", "\">" CRLF,
"filter_select?cwd=%s", name);
- html_quote_string(b, dir);
+ html_quote_string(b, utf8_from_imaputf7(pool, dir));
bprintf(b, "</a></td>" CRLF);
bputs(b, "</tr>" CRLF);
@@ -93,7 +93,7 @@ generate_favourite_folder_line(struct se
bputs(b, "</td>" CRLF);
bputs(b, "<td>" CRLF);
- html_quote_string(b, folder);
+ html_quote_string(b, utf8_from_imaputf7(pool, folder));
bputs(b, "</td>" CRLF);
html_textlink_mailbox_table(session, b, "filter_mbox/copy", name,
@@ -124,7 +124,7 @@ generate_folder_line(struct session *ses
bputs(b, "</td>" CRLF);
bputs(b, "<td>" CRLF);
- html_quote_string(b, folder);
+ html_quote_string(b, utf8_from_imaputf7(pool, folder));
bputs(b, "</td>" CRLF);
html_textlink_mailbox_table(session, b, "filter_mbox/copy", name,
@@ -159,8 +159,8 @@ html_folderlist(struct session *session,
/* Change directory form, including back button */
html_form_start(session, b, "GET", "filter_select");
- html_form_field(b, "Directory", "cwd", session->cwd, 32);
- html_form_field(b, "Filter", "filter", session->dir_filter, 12);
+ html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
+ html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
html_form_submit(b, "sub_apply", "Apply");
html_form_submit(b, "sub_cancel", "Cancel");
html_form_end(b);
Index: prayer-1.0.18/prayer/cmd_folders.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_folders.c 2007-03-10 19:38:54.249401166 +0100
+++ prayer-1.0.18/prayer/cmd_folders.c 2007-03-10 19:39:30.734099143 +0100
@@ -95,7 +95,7 @@ generate_directory_line(struct session *
html_session_bprintf(session, b, "<td><a href=\"", "\">" CRLF,
"folders?cwd=%s", name);
- html_quote_string(b, dir);
+ html_quote_string(b, utf8_from_imaputf7(pool, dir));
bprintf(b, "</a></td>" CRLF);
html_textlink_mailbox_table(session, b, "rename", name, "Rename");
@@ -127,7 +127,7 @@ generate_folder_line(struct session *ses
html_session_bprintf(session, b, "<td nowrap><a href=\"", "\">" CRLF,
"change/%s", name);
- html_quote_string(b, folder);
+ html_quote_string(b, utf8_from_imaputf7(pool, folder));
bprintf(b, "</a></td>" CRLF);
if (strcmp(name, "INBOX") != 0) {
@@ -165,8 +165,8 @@ html_folderlist(struct session *session,
else
bputs(b, "<tr>");
bputs(b, "<td><table><tr><td>" CRLF);
- html_form_field(b, "Directory", "cwd", session->cwd, 32);
- html_form_field(b, "Filter", "filter", session->dir_filter, 12);
+ html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
+ html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
html_form_submit(b, "submit", "Apply");
bputs(b, "</td></tr></table></td>" CRLF);
bputs(b, "<td align=\"right\"><table><tr>" CRLF);
@@ -267,7 +267,7 @@ void cmd_folders(struct session *session
request_decode_get(request);
h = request->form;
- if ((s = assoc_lookup(h, "cwd"))) {
+ if ((s = utf8_to_imaputf7(request->pool, assoc_lookup(h, "cwd")))) {
string_canon_decode(s);
if (string_filename_valid(s))
@@ -277,7 +277,7 @@ void cmd_folders(struct session *session
"Path contained illegal characters");
}
- if ((s = assoc_lookup(h, "filter"))
+ if ((s = utf8_to_imaputf7(request->pool, assoc_lookup(h, "filter")))
&& (strcmp(s, session->dir_filter) != 0))
string_strdup(&session->dir_filter, s);
}
Index: prayer-1.0.18/prayer/cmd_forward1.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_forward1.c 2007-03-10 19:38:54.309408891 +0100
+++ prayer-1.0.18/prayer/cmd_forward1.c 2007-03-10 19:39:30.744100430 +0100
@@ -157,6 +157,8 @@ add_text(struct session *session,
char *init_msg, *decode_msg, *type;
BODY *body = NIL;
char *section = "1";
+ PARAMETER *parameter;
+ char *charset = "ISO-8859-1";
if (!(text = ml_fetch_header(session, stream, msgno,
NIL, hdrslist, &len, 0)))
@@ -204,6 +206,13 @@ add_text(struct session *session,
} else
section = "1";
+ for (parameter = body->parameter; parameter; parameter = parameter->next) {
+ if (strcasecmp(parameter->attribute, "charset") == 0) {
+ charset = parameter->value;
+ break;
+ }
+ }
+
if (!(init_msg = ml_fetchbody(session, stream, msgno, section, &len)))
return (NIL);
Index: prayer-1.0.18/prayer/cmd_list.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_list.c 2007-03-10 19:38:54.379417906 +0100
+++ prayer-1.0.18/prayer/cmd_list.c 2007-03-10 19:39:30.794106870 +0100
@@ -143,7 +143,7 @@ cmd_list_toolbar_hdr(struct session *ses
bputs(b, "</tr></table></td>" CRLF);
bputs(b, "<td width=\"33%\" align=\"center\"><strong>\"");
- html_quote_string(b, session->foldername);
+ html_quote_string(b, utf8_from_imaputf7(session->request->pool, session->foldername));
bputs(b, "\" with ");
bprintf(b, "%lu%s %s" CRLF, count, marked, messages);
bputs(b, "</strong></td>" CRLF);
@@ -378,7 +378,7 @@ cmd_list_msg(struct session *session,
(char *) rfc1522_decode(pool_alloc(request->pool, strlen(string)),
strlen(string), string, NIL);
- string = string_prune(request->pool, string, config->list_addr_maxlen);
+ string = utf8_prune(request->pool, string, config->list_addr_maxlen);
if (use_to)
string = pool_strcat(request->pool, "To: ", string);
@@ -400,7 +400,7 @@ cmd_list_msg(struct session *session,
rfc1522_decode(pool_alloc(request->pool, strlen(string)),
strlen(string), string, NIL);
- string = string_prune(request->pool, string,
+ string = utf8_prune(request->pool, string,
config->list_subject_maxlen);
} else
string = "(No subject)";
Index: prayer-1.0.18/prayer/cmd_preferred.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_preferred.c 2007-03-10 19:38:54.429424344 +0100
+++ prayer-1.0.18/prayer/cmd_preferred.c 2007-03-10 19:39:30.824110733 +0100
@@ -22,7 +22,8 @@ void cmd_preferred(struct session *sessi
if (string_filename_valid(name)) {
favourite_preferred(fl, name);
options->save = T;
- session_message(session, "Making %s preferred folder", name);
+ session_message(session, "Making %s preferred folder",
+ utf8_from_imaputf7(request->pool, name));
} else
session_message(session,
"String contained illegal characters");
Index: prayer-1.0.18/prayer/cmd_rename.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_rename.c 2007-03-10 19:38:54.499433358 +0100
+++ prayer-1.0.18/prayer/cmd_rename.c 2007-03-10 19:39:30.844113310 +0100
@@ -63,7 +63,7 @@ generate_directory_line(struct session *
bprintf(b, "</a></td>" CRLF);
html_session_bprintf(session, b, "<td><a href=\"", "\">" CRLF,
"rename?cwd=%s", name);
- html_quote_string(b, dir);
+ html_quote_string(b, utf8_from_imaputf7(pool, dir));
bprintf(b, "</a></td></tr>" CRLF);
}
@@ -84,7 +84,7 @@ generate_folder_line(struct session *ses
html_icon(session, b, "dir.gif", "[mailbox]");
bputs(b, "</a></td>" CRLF);
bputs(b, "<td><a>" CRLF);
- html_quote_string(b, folder);
+ html_quote_string(b, utf8_from_imaputf7(pool, folder));
bputs(b, "</a></td></tr>" CRLF);
}
@@ -107,7 +107,7 @@ rename_html_folderlist(struct session *s
if (session->rename_foldername)
bprintf(b,
"<h2 align=\"center\">Rename folder %s to ...</h2>" CRLF,
- session->rename_foldername);
+ utf8_from_imaputf7(pool, session->rename_foldername));
/* Change directory form, including back button */
html_form_start(session, b, "GET", "rename");
@@ -118,8 +118,8 @@ rename_html_folderlist(struct session *s
else
bputs(b, "<tr>");
bputs(b, "<td>" CRLF);
- html_form_field(b, "Directory", "cwd", session->cwd, 32);
- html_form_field(b, "Filter", "filter", session->dir_filter, 12);
+ html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
+ html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
html_form_submit(b, "submit", "Apply");
bputs(b, "</td></tr></table>" CRLF);
html_form_end(b);
Index: prayer-1.0.18/prayer/cmd_rename_item.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_rename_item.c 2007-03-10 19:38:54.569442372 +0100
+++ prayer-1.0.18/prayer/cmd_rename_item.c 2007-03-10 19:39:30.864115885 +0100
@@ -29,7 +29,7 @@ void cmd_rename_item(struct session *ses
}
if (!(session->rename_foldername &&
- (newname = assoc_lookup(request->form, "name")))) {
+ (newname = utf8_to_imaputf7(pool, assoc_lookup(request->form, "name"))))) {
session_redirect(session, request, "folders");
return;
}
@@ -70,11 +70,13 @@ void cmd_rename_item(struct session *ses
if (ml_have_error()) {
session_message(session,
"Failed to rename mailbox: %s - %s",
- session->rename_foldername, ml_errmsg());
+ utf8_from_imaputf7(pool, session->rename_foldername),
+ ml_errmsg());
} else {
session_message(session,
"Renamed mailbox %s to be %s",
- session->rename_foldername, newname);
+ utf8_from_imaputf7(pool, session->rename_foldername),
+ newname);
dircache_rename(session->dircache, session->rename_foldername,
newname);
}
Index: prayer-1.0.18/prayer/cmd_reply2.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_reply2.c 2007-03-10 19:38:54.619448812 +0100
+++ prayer-1.0.18/prayer/cmd_reply2.c 2007-03-10 19:39:30.894119749 +0100
@@ -51,6 +51,8 @@ add_text(struct session *session, struct
char *init_msg, *decode_msg, *type;
unsigned long len;
char *text, *s;
+ PARAMETER *parameter;
+ char *charset = "ISO-8859-1";
if ((body = ml_body(session, stream, msgno, "1")) == NIL)
return(NIL);
@@ -91,6 +93,13 @@ add_text(struct session *session, struct
return(T);
}
+ for (parameter = body->parameter; parameter; parameter = parameter->next) {
+ if (strcasecmp(parameter->attribute, "charset") == 0) {
+ charset = parameter->value;
+ break;
+ }
+ }
+
/* Got a valid text section to display */
if (!(init_msg=ml_fetchbody(session, stream, msgno, section, &len)))
return(NIL);
@@ -133,11 +142,11 @@ add_text(struct session *session, struct
struct buffer *b = buffer_create(pool, 8192);
if (decode_msg == init_msg)
decode_msg = strdup(init_msg);
- html_secure_strip_all(b, decode_msg);
+ html_secure_strip_all(b, utf8_from_string(pool, charset, decode_msg, len));
text = buffer_fetch(b, 0, buffer_size(b), NIL);
} else
- text = decode_msg;
+ text = utf8_from_string(pool, charset, decode_msg, len);
bputs(b, ">");
for (s = text; *s;) {
Index: prayer-1.0.18/prayer/cmd_rm.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_rm.c 2007-03-10 19:38:54.669455249 +0100
+++ prayer-1.0.18/prayer/cmd_rm.c 2007-03-10 19:39:30.914122325 +0100
@@ -32,16 +32,20 @@ void cmd_rm(struct session *session)
bprintf(b,
"<h2 align=\"center\">Confirm directory deletion: \"%s\"</h2>"
CRLF,
- string_canon_decode(pool_strdup
- (request->pool, request->argv[2])));
+ utf8_from_imaputf7(request->pool,
+ string_canon_decode(pool_strdup
+ (request->pool,
+ request->argv[2]))));
} else {
html_start(session, b, "Confirm Mail folder deletion");
bprintf(b,
"<h2 align=\"center\">Confirm folder deletion: \"%s\"</h2>"
CRLF,
- string_canon_decode(pool_strdup
- (request->pool, request->argv[2])));
+ utf8_from_imaputf7(request->pool,
+ string_canon_decode(pool_strdup
+ (request->pool,
+ request->argv[2]))));
}
cmd = pool_printf(request->pool, "rm1/%s/%s",
Index: prayer-1.0.18/prayer/cmd_rm1.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_rm1.c 2007-03-10 19:38:54.719461687 +0100
+++ prayer-1.0.18/prayer/cmd_rm1.c 2007-03-10 19:39:30.944126189 +0100
@@ -55,7 +55,7 @@ void cmd_rm1(struct session *session)
session_message(session, "%s", ml_errmsg()); /* Includes name */
} else {
session_message(session, "Deleted directory: \"%s\"", mailbox);
- dircache_delete(session->dircache, mailbox);
+ dircache_delete(session->dircache, utf8_from_imaputf7(request->pool, mailbox));
}
} else {
ml_delete(session, stream,
@@ -67,7 +67,8 @@ void cmd_rm1(struct session *session)
} else if (ml_have_error()) {
session_message(session, "%s", ml_errmsg()); /* Includes name */
} else {
- session_message(session, "Deleted mailbox: \"%s\"", mailbox);
+ session_message(session, "Deleted mailbox: \"%s\"",
+ utf8_from_imaputf7(request->pool, mailbox));
dircache_delete(session->dircache, mailbox);
if (favourite_delete(fl, mailbox))
options->save = T;
Index: prayer-1.0.18/prayer/cmd_subscribe.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_subscribe.c 2007-03-10 19:38:54.769468126 +0100
+++ prayer-1.0.18/prayer/cmd_subscribe.c 2007-03-10 19:39:30.954127477 +0100
@@ -23,7 +23,7 @@ void cmd_subscribe(struct session *sessi
if (favourite_add(fl, name)) {
options->save = T;
session_message(session, "Added %s to favourites list",
- name);
+ utf8_from_imaputf7(request->pool, name));
} else
session_message(session, "Already on favourites list",
name);
Index: prayer-1.0.18/prayer/cmd_transfer.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_transfer.c 2007-03-10 19:38:54.829475852 +0100
+++ prayer-1.0.18/prayer/cmd_transfer.c 2007-03-10 19:39:30.994132629 +0100
@@ -93,7 +93,7 @@ generate_directory_line(struct session *
html_session_bprintf(session, b,
"<td><a href=\"", "\">" CRLF, "transfer?cwd=%s",
name);
- html_quote_string(b, dir);
+ html_quote_string(b, utf8_from_imaputf7(pool, dir));
bprintf(b, "</a></td>" CRLF);
bputs(b, "<td> </td>" CRLF);
@@ -125,7 +125,7 @@ generate_favourite_folder_line(struct se
bputs(b, "</a></td>" CRLF);
bputs(b, "<td><a>" CRLF);
- html_quote_string(b, folder);
+ html_quote_string(b, utf8_from_imaputf7(pool, folder));
bputs(b, "</a></td>" CRLF);
bprintf(b, "<td><a href=\"%s/NOSEQ/transfer/%s/%s\">" CRLF,
@@ -159,7 +159,7 @@ generate_folder_line(struct session *ses
bputs(b, "</a></td>" CRLF);
bputs(b, "<td>" CRLF);
- html_quote_string(b, folder);
+ html_quote_string(b, utf8_from_imaputf7(pool, folder));
bputs(b, "</td>" CRLF);
bprintf(b, "<td><a href=\"%s/NOSEQ/transfer/%s/%s\">" CRLF,
@@ -197,8 +197,8 @@ html_folderlist(struct session *session,
else
bputs(b, "<tr>");
bputs(b, "<td><table><tr><td>" CRLF);
- html_form_field(b, "Directory", "cwd", session->cwd, 32);
- html_form_field(b, "Filter", "filter", session->dir_filter, 12);
+ html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
+ html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
html_form_submit(b, "submit", "Apply");
bputs(b, "</td></tr></table></td>" CRLF);
bputs(b, "<td align=\"right\"><table><tr><td>" CRLF);
@@ -332,7 +332,8 @@ static BOOL download(struct session *ses
OP_READONLY);
if (!session->xfer_stream) {
- session_message(session, "Failed to open mail folder: %s", name);
+ session_message(session, "Failed to open mail folder: %s",
+ utf8_from_imaputf7(request->pool, name));
session_log(session,
"[cmd_transfer] Failed to open mail folder: %s", name);
return (NIL);
@@ -343,7 +344,7 @@ static BOOL download(struct session *ses
/* Fetch overview for all messages in folder */
if (!ml_fetch_overview(session, tstream, "1:*", NIL)) {
session_message(session, "Failed to fetch folder overview: %s",
- name);
+ utf8_from_imaputf7(request->pool, name));
session_log(session,
"[cmd_transfer]] Failed to fetch overview: %s", name);
return (NIL);
Index: prayer-1.0.18/prayer/cmd_unsubscribe.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_unsubscribe.c 2007-03-10 19:38:54.919487442 +0100
+++ prayer-1.0.18/prayer/cmd_unsubscribe.c 2007-03-10 19:39:31.014135204 +0100
@@ -23,10 +23,11 @@ void cmd_unsubscribe(struct session *ses
if (favourite_delete(fl, name)) {
options->save = T;
session_message(session, "Removed %s from favourites list",
- name);
+ utf8_from_imaputf7(request->pool, name));
} else
session_message(session,
- "Folder %s not on favourites list", name);
+ "Folder %s not on favourites list",
+ utf8_from_imaputf7(request->pool, name));
} else
session_message(session,
"String contained illegal characters");
Index: prayer-1.0.18/prayer/cmd_upload_select.c
===================================================================
--- prayer-1.0.18.orig/prayer/cmd_upload_select.c 2007-03-10 19:38:54.969493881 +0100
+++ prayer-1.0.18/prayer/cmd_upload_select.c 2007-03-10 19:39:31.034137781 +0100
@@ -122,8 +122,8 @@ html_folderlist(struct session *session,
/* Change directory form, including back button */
html_form_start(session, b, "GET", "upload_select");
- html_form_field(b, "Directory", "cwd", session->cwd, 32);
- html_form_field(b, "Filter", "filter", session->dir_filter, 12);
+ html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
+ html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
html_form_submit(b, "submit", "Apply");
html_form_end(b);
Index: prayer-1.0.18/prayer/draft.c
===================================================================
--- prayer-1.0.18.orig/prayer/draft.c 2007-03-10 19:38:55.019500318 +0100
+++ prayer-1.0.18/prayer/draft.c 2007-03-10 19:39:31.074142931 +0100
@@ -477,7 +477,7 @@ void draft_update_body(struct draft *d,
} else
d->body = pool_strdup(d->pool, d->body);
- draft_transliterate_1252((unsigned char *)d->body);
+ /*draft_transliterate_1252((unsigned char *)d->body);*/
}
/* draft_update() ********************************************************
@@ -535,7 +535,7 @@ void draft_update(struct draft *d, struc
else
d->body = pool_maybe_strdup(d->pool, d->body);
- draft_transliterate_1252((unsigned char *)d->body);
+ /*draft_transliterate_1252((unsigned char *)d->body);*/
d->in_reply_to = pool_maybe_strdup(d->pool, d->in_reply_to);
d->references = pool_maybe_strdup(d->pool, d->references);
@@ -1164,7 +1164,7 @@ static void draft_make_multipart(struct
bprintf(b, CRLF "--%s" CRLF, cookie);
bputs(b,
- "Content-Type: text/plain; format=flowed; charset=ISO-8859-1"
+ "Content-Type: text/plain; format=flowed; charset=UTF-8"
CRLF);
if (need_qprint)
bputs(b, "Content-Transfer-Encoding: QUOTED-PRINTABLE" CRLF);
@@ -1323,7 +1323,7 @@ static void draft_make_single_part(struc
need_qprint = T;
bputs(b,
- "Content-Type: text/plain; format=flowed; charset=ISO-8859-1"
+ "Content-Type: text/plain; format=flowed; charset=UTF-8"
CRLF);
if (need_qprint)
bputs(b, "Content-Transfer-Encoding: quoted-printable" CRLF);
@@ -1418,7 +1418,7 @@ char *draft_make_msg(struct draft *draft
/* Encode using temporary buffer if required */
s = (char *) rfc1522_encode(tmp, len,
- (unsigned char *) s, "ISO-8859-1");
+ (unsigned char *) s, "UTF-8");
bprintf(mb, "Subject: %s" CRLF, s);
free(tmp);
}
Index: prayer-1.0.18/prayer/html.c
===================================================================
--- prayer-1.0.18.orig/prayer/html.c 2007-03-10 19:38:55.069506757 +0100
+++ prayer-1.0.18/prayer/html.c 2007-03-10 19:39:31.134150660 +0100
@@ -35,7 +35,7 @@ void html_start(struct session *session,
bprintf(b, "<title>Webmail service: %s</title>" CRLF, title);
bputs(b, "<meta name=\"robots\" content=\"none\">" CRLF);
bputs(b, ("<meta http-equiv=\"Content-Type\" "
- "content=\"text/html; charset=ISO-8859-1\">" CRLF));
+ "content=\"text/html; charset=UTF-8\">" CRLF));
bputs(b, "</head>" CRLF);
bputs(b, "<body");
@@ -502,7 +502,7 @@ void
html_form_start(struct session *s, struct buffer *b, char *method,
char *cmd)
{
- bprintf(b, "<form method=\"%s\" accept-charset=\"ISO-8859-1\"",
+ bprintf(b, "<form method=\"%s\" accept-charset=\"UTF-8\"",
method);
html_session_bputs(s, b, " action=\"", "\">" CRLF, cmd);
}
@@ -854,7 +854,7 @@ html_banner_toolbar_favourites(struct se
string_canon_encode(request->pool, li->name));
}
- html_quote_string(b, li->name);
+ html_quote_string(b, utf8_from_imaputf7(request->pool, li->name));
bputs(b, "</option>" CRLF);
}
bputs(b, "</select>" CRLF);
@@ -926,14 +926,14 @@ html_banner_toolbar_folders(struct sessi
if (prefix) {
bprintf(b, "<option value=\"%s%s\">",
prefix, string_canon_encode(request->pool, dl->name));
- html_quote_string(b, session->cwd);
+ html_quote_string(b, utf8_from_imaputf7(request->pool, session->cwd));
html_quote_string(b, "/");
- html_quote_string(b, dl->name);
+ html_quote_string(b, utf8_from_imaputf7(request->pool, dl->name));
bputs(b, "</option>" CRLF);
} else if (strcasecmp(dl->name, "INBOX") != 0) {
bprintf(b, "<option value=\"%s\">",
string_canon_encode(request->pool, dl->name));
- html_quote_string(b, dl->name);
+ html_quote_string(b, utf8_from_imaputf7(request->pool, dl->name));
bputs(b, "</option>" CRLF);
}
}
@@ -1077,7 +1077,8 @@ html_banner_toolbar(struct session *sess
void html_quote_char(struct buffer *b, unsigned char c)
{
if (c > 127) {
- bprintf(b, "&#%lu;", (unsigned long) c);
+ /*bprintf(b, "&#%lu;", (unsigned long) c);*/
+ bputc(b, c);
} else
switch (c) {
case '"':
Index: prayer-1.0.18/prayer/prayer_session.h
===================================================================
--- prayer-1.0.18.orig/prayer/prayer_session.h 2007-03-10 19:39:29.243907238 +0100
+++ prayer-1.0.18/prayer/prayer_session.h 2007-03-10 19:39:31.844242104 +0100
@@ -74,3 +74,4 @@ extern int errno; /* just
#include "checksum.h"
#include "wrap.h"
#include "portlist.h"
+#include "utf8.h"
Index: prayer-1.0.18/prayer/response.c
===================================================================
--- prayer-1.0.18.orig/prayer/response.c 2007-03-10 19:38:55.169519634 +0100
+++ prayer-1.0.18/prayer/response.c 2007-03-10 19:39:31.904249831 +0100
@@ -405,7 +405,7 @@ void response_error(struct request *requ
bputs(b, "Expires: ");
response_date_string(b, time(NIL));
bputs(b, "" CRLF);
- bprintf(b, "Content-Type: text/html; charset=iso-8859-1" CRLF);
+ bprintf(b, "Content-Type: text/html; charset=UTF-8" CRLF);
bprintf(b, "Content-Length: %lu" CRLF,
buffer_size(request->write_buffer));
response_header_end(request);
@@ -437,7 +437,7 @@ void response_html(struct request *reque
/* Generate simple header block for HTML */
response_header_start(request, status);
- bputs(b, "Content-Type: text/html; charset=iso-8859-1" CRLF);
+ bputs(b, "Content-Type: text/html; charset=UTF-8" CRLF);
#ifdef STELLA_HACK
bputs(b, "Expires: ");
Index: prayer-1.0.18/prayer/rfc1522.c
===================================================================
--- prayer-1.0.18.orig/prayer/rfc1522.c 2007-03-10 19:38:55.249529936 +0100
+++ prayer-1.0.18/prayer/rfc1522.c 2007-03-10 19:39:31.934253696 +0100
@@ -162,6 +162,7 @@ char **charset;
unsigned char *rv = NULL, *p;
char *start = s, *sw, *cset, *enc, *txt, *ew, **q, *lang;
unsigned long l;
+ unsigned char *src;
int i;
*d = '\0'; /* init destination */
@@ -171,15 +172,16 @@ char **charset;
while (s && (sw = strstr(s, RFC1522_INIT))) {
/* validate the rest of the encoded-word */
if (rfc1522_valid(sw, &cset, &enc, &txt, &ew)) {
- if (!rv)
+ if (!rv)
rv = d; /* remember start of dest */
/* copy everything between s and sw to destination */
for (i = 0; &s[i] < sw; i++)
if (!isspace((unsigned char) s[i])) { /* if some non-whitespace */
- while (s < sw && d - rv < len - 1)
- *d++ = (unsigned char) *s++;
-
+ /* Assume that any 8 bit characters are Latin-1 */
+ utf8_print(VAR_CHAR_SET, NULL,
+ &d, len - (d - rv) - 1,
+ (unsigned char**)&s, sw - s);
break;
}
@@ -188,23 +190,12 @@ char **charset;
if ((lang = strchr(cset, '*')))
*lang++ = '\0';
-
- /* Insert text explaining charset if we don't know what it is */
- if ((strcasecmp((char *) cset, VAR_CHAR_SET))
- && strcasecmp((char *) cset, "US-ASCII")) {
- if (charset) {
- if (!*charset) /* only write first charset */
- *charset = cpystr(cset);
- } else {
- if (d - rv < len - 1)
- *d++ = '[';
-
- sstrncpy((char **) &d, cset, len - 1 - (d - rv));
- if (d - rv < len - 1)
- *d++ = ']';
- if (d - rv < len - 1)
- *d++ = SPACE;
- }
+ if (!*cset) {
+ cset = UNKNOWN_CHARSET;
+ }
+ if (charset) {
+ if (!*charset) /* only write first charset */
+ *charset = cpystr(cset);
}
/* based on encoding, write the encoded text to output buffer */
@@ -228,15 +219,14 @@ char **charset;
} else
q = NULL;
- if ((p =
+ if ((src = p =
rfc822_qprint((unsigned char *) txt, strlen(txt),
&l))) {
- strncpy((char *) d, (char *) p, len - 1 - (d - rv));
- d[len - 1 - (d - rv)] = '\0';
+ utf8_print(cset, VAR_CHAR_SET,
+ &d, len - 1 - (d - rv),
+ &src, l);
+ *d = '\0';
fs_give((void **) &p); /* free encoded buf */
- d += l; /* advance dest ptr to EOL */
- if (d - rv > len - 1)
- d = rv + len - 1;
} else {
if (q)
fs_give((void **) &q);
@@ -255,22 +245,26 @@ char **charset;
case 'B': /* 'B' encoding */
case 'b':
- if ((p =
+ if ((src = p =
rfc822_base64((unsigned char *) txt, strlen(txt),
&l))) {
- strncpy((char *) d, (char *) p, len - 1 - (d - rv));
- d[len - 1 - (d - rv)] = '\0';
+ utf8_print(cset, VAR_CHAR_SET,
+ &d, len - 1 - (d - rv),
+ &src, l);
+ *d = '\0';
fs_give((void **) &p); /* free encoded buf */
- d += l; /* advance dest ptr to EOL */
- if (d - rv > len - 1)
- d = rv + len - 1;
} else
goto bogus;
break;
+ bogus:
default:
- sstrncpy((char **) &d, txt, len - 1 - (d - rv));
+ src = txt;
+ utf8_print(VAR_CHAR_SET, NULL,
+ &d, len - 1 - (d - rv),
+ (unsigned char **)&src, ew - txt);
+ *d = '\0';
break;
}
@@ -283,6 +277,7 @@ char **charset;
if (lang)
lang[-1] = '*';
+
} else {
/*
@@ -291,28 +286,38 @@ char **charset;
/* if already copying to destn, copy it */
if (rv) {
- strncpy((char *) d, s,
- (int) min((l = (sw - s) + RFC1522_INIT_L),
- len - 1 - (d - rv)));
- d += l; /* advance d, tie off text */
- if (d - rv > len - 1)
- d = rv + len - 1;
+ utf8_print(VAR_CHAR_SET, NULL,
+ &d, len - 1 - (d - rv),
+ (unsigned char**)&s, sw - s);
*d = '\0';
- s += l; /* advance s beyond intro */
} else
s += ((sw - s) + RFC1522_INIT_L);
}
}
- if (rv && *s) /* copy remaining text */
- strncat((char *) rv, s, len - 1 - strlen((char *) rv));
+ if (rv && *s) { /* copy remaining text */
+ utf8_print(VAR_CHAR_SET, NULL,
+ &d, len - 1 - (d - rv),
+ (unsigned char**)&s, strlen(s));
+ *d = '\0';
+ }
/* BUG: MUST do code page mapping under DOS after decoding */
- return (rv ? rv : (unsigned char *) start);
+ if (rv) return rv;
+
+ for (s = start; *s; s++) {
+ if (*s & 0x80) {
+ rv = d;
+ utf8_print(VAR_CHAR_SET, NULL,
+ &d, len - 1,
+ (unsigned char**)&start, strlen(s));
+ *d = '\0';
+ return rv;
- bogus:
- return ((unsigned char *) start);
+ }
+ }
+ return (unsigned char *) start;
}
@@ -364,7 +369,7 @@ int c;
int rfc1522_valenc(c)
int c;
{
- return (!(c == '?' || c == SPACE) && isprint((unsigned char) c));
+ return (!(c == '?' /*|| c == SPACE*/) && isprint((unsigned char) c));
}
@@ -386,7 +391,7 @@ char **endp;
&e)
&& rfc1522_token(++e, rfc1522_valtok, RFC1522_DLIM, &t)
&& rfc1522_token(++t, rfc1522_valenc, RFC1522_TERM, &p)
- && p - s <= RFC1522_MAXW;
+ /* && p - s <= RFC1522_MAXW */;
if (charset)
*charset = c;
Index: prayer-1.0.18/prayer/utf8.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ prayer-1.0.18/prayer/utf8.c 2007-03-10 19:39:31.974258848 +0100
@@ -0,0 +1,418 @@
+/* Copyright (c) Magnus Holmgren <magnus@kibibyte.se>,
+ * <holmgren@lysator.liu.se>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "prayer_session.h"
+#include <iconv.h>
+
+#define JNK 0177
+#define UNI_REPLACEMENT_CHAR 0x0000FFFD
+#define UNI_REPLACEMENT_CHAR_UTF8 "\xEF\xBF\xBD"
+#define ICONV_CHUNK_SIZE 1024
+
+/* utf8_from_imaputf7() ***********************************************
+ *
+ * Convert a string encoded as modified UTF-7 to UTF-8.
+ * pool: Target pool for storage
+ * t: The string to convert
+ *
+ * Returns: A new, UTF-8-encoded string
+ *
+ * Note: This function tries hard to return something useful in case
+ * the input string is invalid in some way, rather than bail out
+ * and return NULL.
+ **********************************************************************/
+
+char *utf8_from_imaputf7(struct pool *pool, char *t)
+{
+ struct buffer *b = buffer_create(pool, 64);
+ BOOL base64mode = NIL;
+ int i, j;
+ unsigned char buf[4];
+ unsigned char *s;
+ unsigned long scalar; /* Unicode scalar value */
+ unsigned char c;
+
+ static char decode_base64[256] = {
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,076,077,JNK,JNK,JNK,
+ 064,065,066,067,070,071,072,073,074,075,JNK,JNK,JNK,JNK,JNK,JNK,
+ JNK,000,001,002,003,004,005,006,007,010,011,012,013,014,015,016,
+ 017,020,021,022,023,024,025,026,027,030,031,JNK,JNK,JNK,JNK,JNK,
+ JNK,032,033,034,035,036,037,040,041,042,043,044,045,046,047,050,
+ 051,052,053,054,055,056,057,060,061,062,063,JNK,JNK,JNK,JNK,JNK,
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
+ JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK
+ };
+
+ if (!t) return NULL;
+
+ for (s = (unsigned char*)t; *s; s++) {
+ if (base64mode) {
+ if (*s == '-') {
+ if (j != 0 || c != 0) /* Some junk left */ {
+ bputs(b, UNI_REPLACEMENT_CHAR_UTF8);
+ }
+ base64mode = NIL;
+ continue;
+ }
+
+ if (decode_base64[*s] == JNK) {
+ break; /* Bail out */
+ }
+
+ switch (i++) {
+ case 0:
+ /* Top 6 bits of the first octet */
+ c = decode_base64[*s] << 2; break;
+ case 1:
+ /* Top 2 bits are bottom 2 bits of the first octet */
+ buf[j++] = c | (decode_base64[*s] >> 4);
+ /* and bottom 4 bits are top 4 bits of the second */
+ c = decode_base64[*s] << 4; break;
+ case 2:
+ /* Top 4 bits are bottom 4 bits of the second octet */
+ buf[j++] = c | (decode_base64[*s] >> 2);
+ /* and bottom 2 bits are top 2 bits of the third */
+ c = decode_base64[*s] << 6; break;
+ case 3:
+ /* Bottom 6 bits of the third octet */
+ buf[j++] = c | decode_base64[*s];
+ i = 0;
+ }
+
+ /* Check if we have a complete UTF-16 character */
+ if (j == 4) { /* We should now have a surrogate pair */
+ scalar = ((buf[0] & 3) << 18) + (buf[1] << 10)
+ + ((buf[2] & 3) << 8) + buf[3] + 0x10000;
+ }
+ else if (j == 2) {
+ if (buf[0] < 0xD8 || buf[0] > 0xDF) {
+ scalar = (buf[0] << 8) + buf[1];
+ }
+ else if (buf[0] > 0xDB) {
+ /* Error - invalid surrogate */
+ scalar = UNI_REPLACEMENT_CHAR;
+ }
+ else {
+ /* High surrogate found - need low surrogate */
+ continue;
+ }
+ }
+ else continue; /* Odd number of bytes */
+
+ if (scalar >= 0x110000) scalar = UNI_REPLACEMENT_CHAR;
+
+ if (scalar < 0x80) {
+ bputc(b, (unsigned char)scalar);
+ j = 0;
+ continue;
+ } else if (scalar < 0x800) {
+ bputc(b, 0xC0 | (scalar >> 6));
+ } else if (scalar < 0x10000) {
+ bputc(b, 0xE0 | (scalar >> 12));
+ } else {
+ bputc(b, 0xF0 | (scalar >> 18));
+ }
+
+ if (scalar >= 0x10000)
+ bputc(b, 0x80 | ((scalar >> 12) & 0x3F));
+ if (scalar >= 0x800)
+ bputc(b, 0x80 | ((scalar >> 6) & 0x3F));
+ bputc(b, 0x80 | (scalar & 0x3F));
+ j = 0;
+
+ }
+ else /* !base64mode */ {
+ if (*s == '&') {
+ if (*(s+1) == '-') {
+ bputc(b, '&');
+ s++;
+ }
+ else {
+ base64mode = T;
+ i = 0; j = 0; c = 0;
+ }
+ }
+ else {
+ bputc(b, *s);
+ }
+ }
+ }
+ return buffer_fetch(b, 0, buffer_size(b), NIL);
+}
+
+
+/* utf8_to_imaputf7() *************************************************
+ *
+ * Convert a string encoded as UTF-8 to modified UTF-7.
+ * pool: Target pool for storage
+ * t: The string to convert
+ *
+ * Returns: A new string encoded as modified UTF-7
+ *
+ * Note: This function tries hard to return something useful in case
+ * the input string is invalid in some way, rather than bail out
+ * and return NULL.
+ **********************************************************************/
+
+char *utf8_to_imaputf7(struct pool *pool, char *t)
+{
+ unsigned char *s;
+ struct buffer *b = buffer_create(pool, 64);
+ BOOL base64mode = NIL;
+ unsigned long scalar;
+ unsigned int L, i, j;
+ unsigned char buf[4];
+ unsigned char c = 0;
+
+ static char encode_base64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
+ if (!t) return NULL;
+
+ for (s = (unsigned char *)t; *s; s++) {
+ if (*s < 0x7f && *s >= 0x20) {
+ if (base64mode) {
+ switch (i) {
+ case 1:
+ /* Remaining bottom 2 bits of the last octet */
+ bputc(b, encode_base64[c << 4]); break;
+ case 2:
+ /* Remaining bottom 4 bits of the last octet */
+ bputc(b, encode_base64[c << 2]);
+ }
+ bputc(b, '-');
+ base64mode = NIL;
+ }
+ bputc(b, *s);
+ if (*s == '&') {
+ bputc(b, '-');
+ }
+ }
+ else {
+ if (*s < 0x80) {
+ L = 0; scalar = *s;
+ } else if ((*s & 0xE0) == 0xC0) {
+ L = 1; scalar = (*s & 0x1F);
+ } else if ((*s & 0xF0) == 0xE0) {
+ L = 2; scalar = (*s & 0x0F);
+ } else if ((*s & 0xF8) == 0xF0) {
+ L = 3; scalar = (*s & 0x07);
+ } else if ((*s & 0xFC) == 0xF8) {
+ L = 4; scalar = (*s & 0x03);
+ } else if ((*s & 0xFE) == 0xFC) {
+ L = 5; scalar = (*s & 0x01);
+ } else {
+ L = 0; scalar = UNI_REPLACEMENT_CHAR;
+ }
+
+ for (j = 0; j < L; j++) {
+ s++;
+ if ((*s & 0xC0) == 0x80) {
+ scalar <<= 6;
+ scalar |= (*s & 0x3F);
+ }
+ else {
+ s--;
+ scalar = UNI_REPLACEMENT_CHAR;
+ }
+ }
+
+ if (!base64mode) {
+ bputc(b, '&');
+ base64mode = T;
+ i = 0;
+ }
+ if (scalar <= 0xFFFF) {
+ buf[1] = scalar & 0xFF;
+ scalar >>= 8;
+ buf[0] = scalar & 0xFF;
+ L = 2;
+ }
+ else {
+ scalar -= 0x100000UL;
+ buf[3] = scalar & 0xFF;
+ scalar >>= 8;
+ buf[2] = 0xDC | (scalar & 0x03);
+ scalar >>= 2;
+ buf[3] = scalar & 0xFF;
+ scalar >>= 8;
+ buf[1] = 0xD8 | (scalar & 0x03);
+ L = 4;
+ }
+
+ for (j = 0; j < L; j++) {
+ switch (i++) {
+ case 0:
+ /* Top 6 bits of the first octet */
+ bputc(b, encode_base64[(buf[j] >> 2) & 0x3F]);
+ c = (buf[j] & 0x03); break;
+ case 1:
+ /* Bottom 2 bits of the first octet, and top 4 bits of the second */
+ bputc(b, encode_base64[(c << 4) |
+ ((buf[j] >> 4) & 0x0F)]);
+ c = (buf[j] & 0x0F); break;
+ case 2:
+ /* Bottom 4 bits of the second octet and top 2 bits of the third */
+ bputc(b, encode_base64[(c << 2) |
+ ((buf[j] >> 6) & 0x03)]);
+ /* Bottom 6 bits of the third octet */
+ bputc(b, encode_base64[buf[j] & 0x3F]);
+ i = 0;
+ }
+ }
+
+ }
+ }
+ if (base64mode) {
+ switch (i) {
+ case 1:
+ /* Remaining bottom 2 bits of the last octet */
+ bputc(b, encode_base64[c << 4]); break;
+ case 2:
+ /* Remaining bottom 4 bits of the last octet */
+ bputc(b, encode_base64[c << 2]);
+ }
+ bputc(b, '-');
+ base64mode = NIL;
+ }
+ return buffer_fetch(b, 0, buffer_size(b), NIL);
+}
+
+
+/* utf8_from_string() ************************************************
+ *
+ * Convert a string with given character encoding to UTF-8
+ *
+ * pool: Pool to allocate memory from
+ * charset: Charset of input string
+ * t: String to convert
+ * len: Length of string
+ ***********************************************************************/
+
+char *utf8_from_string(struct pool *pool, char *charset, char *t, unsigned long len)
+{
+ struct buffer *b;
+ char chunk[ICONV_CHUNK_SIZE];
+ char *outbuf;
+ size_t outbytesleft;
+ size_t result;
+ int i;
+ iconv_t cd = iconv_open("UTF-8", charset);
+ b = buffer_create(pool, 1024);
+
+ if (cd == (iconv_t)(-1)) {
+ buffer_printf(b, "(Conversion from %s failed)", charset);
+ }
+ else while (len) {
+ outbuf = chunk;
+ outbytesleft = ICONV_CHUNK_SIZE;
+ result = iconv(cd, &t, (size_t*)&len, &outbuf, &outbytesleft);
+ for (i = 0; i < ICONV_CHUNK_SIZE - outbytesleft; i++) {
+ bputc(b, chunk[i]);
+ }
+ if (result == (size_t)(-1)) switch (errno) {
+ case E2BIG:
+ break;
+ case EILSEQ:
+ case EINVAL:
+ /* Try skipping a byte */
+ t++;
+ len--;
+ bputs(b, UNI_REPLACEMENT_CHAR_UTF8);
+ break;
+ default:
+ iconv_close(cd);
+ return NULL;
+ }
+ }
+
+ iconv_close(cd);
+ return buffer_fetch(b, 0, buffer_size(b), NIL);
+}
+
+BOOL utf8_print(char *charset, char *fallback_charset,
+ unsigned char **dst, unsigned long dst_size,
+ unsigned char **src, unsigned long src_size)
+{
+
+ iconv_t cd = iconv_open("UTF-8", charset);
+ if (cd == (iconv_t)(-1) && fallback_charset)
+ cd = iconv_open("UTF-8", fallback_charset);
+
+ while (iconv(cd, (char**)src, (size_t*)&src_size,
+ (char**)dst, (size_t*)&dst_size) == (size_t)(-1)) {
+ switch (errno) {
+ case EILSEQ:
+ case EINVAL:
+ /* Try skipping a byte */
+ (*src)++;
+ src_size--;
+ if (dst_size >= sizeof(UNI_REPLACEMENT_CHAR_UTF8)) {
+ strcpy((char*)*dst, UNI_REPLACEMENT_CHAR_UTF8);
+ }
+ if (errno == EILSEQ) break;
+ case E2BIG:
+ default:
+ iconv_close(cd);
+ return NIL;
+ }
+ }
+ iconv_close(cd);
+ return T;
+}
+
+/* utf8_prune() ********************************************************
+ *
+ * Like string_prune, but counts UTF-8 multibyte sequences as units.
+ * pool: Target pool
+ * s: UTF-8 string to prune
+ * maxlen: Maximum length of string before pruning applies.
+ *
+ * Returns: Pruned string, maximum maxlen characters (not bytes), not
+ * counting the terminating null.
+ ***********************************************************************/
+
+char *utf8_prune(struct pool *pool, char *s, unsigned long maxlen)
+{
+ char *result;
+ unsigned long cutoff;
+ unsigned long L;
+ unsigned long i = 0;
+
+ if (maxlen < (strlen("...") + 1))
+ return (s);
+
+ for (L = 0; L < maxlen; L++) {
+ if (s[i] == '\0') return s;
+ if (L == maxlen - strlen("...")) cutoff = i;
+
+ if (s[i] & 0x80)
+ while (s[i] & 0x80) i++;
+ else
+ i++;
+ }
+
+ result = pool_alloc(pool, cutoff + 4);
+ memcpy(result, s, cutoff);
+ strcpy(result + cutoff, "...");
+
+ return (result);
+
+}
Index: prayer-1.0.18/prayer/utf8.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ prayer-1.0.18/prayer/utf8.h 2007-03-10 19:39:32.004262711 +0100
@@ -0,0 +1,7 @@
+char *utf8_from_imaputf7(struct pool *pool, char *t);
+char *utf8_to_imaputf7(struct pool *pool, char *t);
+char *utf8_from_string(struct pool *pool, char *charset, char *t, unsigned long len);
+BOOL utf8_print(char *charset, char *fallback_charset,
+ unsigned char **dst, unsigned long dst_size,
+ unsigned char **src, unsigned long src_size);
+char *utf8_prune(struct pool *pool, char *s, unsigned long maxlen);