Subversion Repositories

?revision_form?Rev ?revision_input??revision_submit??revision_endform?

Rev 3 | Blame | Compare with Previous | 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>&nbsp;</td>" CRLF);
     bputs(b, "<td>&nbsp;</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>&nbsp;</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);