Subversion Repositories

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

Rev 3 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 magnus 1
This patch adds support for UTF-8 and modified UTF-7. Functions are in
2
the new utf8.c. The patch adds calls to utf8_to_imaputf7() or
3
utf8_from_imaputf7() wherever a folder name is handled in the code. In
4
addition, it changes prayer to use UTF-8 in all HTML output as well as
5
in composition of messages.
6
Index: prayer-1.0.18/prayer/Makefile
7
===================================================================
8
--- prayer-1.0.18.orig/prayer/Makefile  2007-03-10 19:39:29.563948453 +0100
9
+++ prayer-1.0.18/prayer/Makefile       2007-03-10 19:39:30.294042473 +0100
10
@@ -127,7 +127,7 @@ SESSION_SUPPORT_OBJS = \
11
    abook.o lookup.o role.o dictionary.o \
12
    options.o rfc1522.o banner.o favourite.o wrap.o portlist.o \
13
    account.o account_msshell.o account_sieve.o account_support.o \
14
-   sieve.o filter.o checksum.o
15
+   sieve.o filter.o checksum.o utf8.o
16
 
17
 ifeq ($(strip $(SESSION_NEEDS_DB)), true)
18
    SESSION_SUPPORT_OBJS += mydb_db3.o
19
Index: prayer-1.0.18/prayer/cmd_change.c
20
===================================================================
21
--- prayer-1.0.18.orig/prayer/cmd_change.c      2007-03-10 19:38:53.659325192 +0100
22
+++ prayer-1.0.18/prayer/cmd_change.c   2007-03-10 19:39:30.344048912 +0100
23
@@ -16,7 +16,7 @@ void cmd_change(struct session *session)
24
     if (request->method == POST) {
25
         request_decode_post(request);
26
 
27
-        if (!(name = assoc_lookup(request->form, "folder"))) {
28
+        if (!(name = utf8_to_imaputf7(request->pool, assoc_lookup(request->form, "folder")))) {
29
             session_redirect(session, request, "error");
30
             return;
31
         }
32
@@ -30,7 +30,8 @@ void cmd_change(struct session *session)
33
     }
34
 
35
     if (!session_streams_change(session, name)) {
36
-        session_message(session, "Unable to switch to folder: %s", name);
37
+        session_message(session, "Unable to switch to folder: %s",
38
+                        utf8_from_imaputf7(request->pool, name));
39
         session_redirect(session, request, "restart");
40
         return;
41
     }
42
@@ -47,7 +48,7 @@ void cmd_change(struct session *session)
43
     }
44
 
45
     session_message(session, "Switched to mailbox: %s",
46
-                    session->foldername);
47
+                    utf8_from_imaputf7(request->pool, session->foldername));
48
     session_log(session, "[cmd_change] Switched to mailbox: %s",
49
                 session->foldername);
50
 
51
Index: prayer-1.0.18/prayer/cmd_compose.c
52
===================================================================
53
--- prayer-1.0.18.orig/prayer/cmd_compose.c     2007-03-10 19:38:53.719332917 +0100
54
+++ prayer-1.0.18/prayer/cmd_compose.c  2007-03-10 19:39:30.384054064 +0100
55
@@ -244,7 +244,7 @@ static BOOL cmd_compose_generate_postpon
56
                            strlen(string), string, NIL);
57
 
58
         string =
59
-            string_prune(request->pool, string, config->list_addr_maxlen);
60
+            utf8_prune(request->pool, string, config->list_addr_maxlen);
61
 
62
         bputs(b, "<td>" CRLF);
63
         html_quote_string(b, string);
64
@@ -267,7 +267,7 @@ static BOOL cmd_compose_generate_postpon
65
                 rfc1522_decode(pool_alloc(request->pool, strlen(string)),
66
                                strlen(string), string, NIL);
67
 
68
-            string = string_prune(request->pool, string,
69
+            string = utf8_prune(request->pool, string,
70
                                   config->list_subject_maxlen);
71
         } else
72
             string = "(No subject)";
73
Index: prayer-1.0.18/prayer/cmd_copy.c
74
===================================================================
75
--- prayer-1.0.18.orig/prayer/cmd_copy.c        2007-03-10 19:38:53.769339356 +0100
76
+++ prayer-1.0.18/prayer/cmd_copy.c     2007-03-10 19:39:30.404056640 +0100
77
@@ -95,7 +95,7 @@ generate_directory_line(struct session *
78
     html_session_bprintf(session, b,
79
                          "<td><a href=\"", "\">" CRLF, "copy?cwd=%s",
80
                          name);
81
-    html_quote_string(b, dir);
82
+    html_quote_string(b, utf8_from_imaputf7(pool, dir));
83
     bprintf(b, "</a></td>" CRLF);
84
 
85
     bputs(b, "</tr>" CRLF);
86
@@ -127,7 +127,7 @@ generate_favourite_folder_line(struct se
87
     html_session_bprintf(session, b,
88
                          "<td><a href=\"", "\">" CRLF, "copy_msg/%s",
89
                          name);
90
-    html_quote_string(b, folder);
91
+    html_quote_string(b, utf8_from_imaputf7(pool, folder));
92
     bprintf(b, "</a></td>" CRLF);
93
 
94
     bputs(b, "</tr>" CRLF);
95
@@ -159,7 +159,7 @@ generate_folder_line(struct session *ses
96
     html_session_bprintf(session, b,
97
                          "<td><a href=\"", "\">" CRLF, "copy_msg/%s",
98
                          name);
99
-    html_quote_string(b, folder);
100
+    html_quote_string(b, utf8_from_imaputf7(pool, folder));
101
     bprintf(b, "</a></td>" CRLF);
102
 
103
     bprintf(b, "</tr>" CRLF);
104
@@ -209,8 +209,8 @@ html_folderlist(struct session *session,
105
         bputs(b, "<tr>");
106
     bputs(b, "<td>");
107
     bputs(b, "<table><tr><td>" CRLF);
108
-    html_form_field(b, "Directory", "cwd", session->cwd, 32);
109
-    html_form_field(b, "Filter", "filter", session->dir_filter, 12);
110
+    html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
111
+    html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
112
     html_form_submit(b, "submit", "Apply");
113
     bputs(b, "</td></tr></table>" CRLF);
114
     bputs(b, "<td align=\"right\"><table><tr><td>" CRLF);
115
Index: prayer-1.0.18/prayer/cmd_copy_msg.c
116
===================================================================
117
--- prayer-1.0.18.orig/prayer/cmd_copy_msg.c    2007-03-10 19:38:53.829347082 +0100
118
+++ prayer-1.0.18/prayer/cmd_copy_msg.c 2007-03-10 19:39:30.484066944 +0100
119
@@ -125,12 +125,13 @@ void cmd_copy_msg(struct session *sessio
120
         /* Keep current message */
121
         if (count > 1) {
122
             session_message(session, "Copied %lu messages to %s", count,
123
-                            mailbox);
124
+                            utf8_from_imaputf7(request->pool, mailbox));
125
             session_log(session,
126
                         "[cmd_copy_msg] Copied %lu messages to %s", count,
127
                         mailbox);
128
         } else if (count == 1) {
129
-            session_message(session, "Copied 1 message to %s", mailbox);
130
+            session_message(session, "Copied 1 message to %s",
131
+                            utf8_from_imaputf7(request->pool, mailbox));
132
             session_log(session, "[cmd_copy_msg] Copied 1 message to %s",
133
                         mailbox);
134
         } else {
135
@@ -152,9 +153,8 @@ void cmd_copy_msg(struct session *sessio
136
         next = msgmap_value(zm, zm_offset + 1);
137
     else {
138
         /* No next message */
139
-        session_message(session,
140
-                        "Copied message %lu to \"%s\", no more messages",
141
-                        msgno, mailbox);
142
+        session_message(session, "Copied message %lu to \"%s\", no more messages",
143
+                        msgno, utf8_from_imaputf7(request->pool, mailbox));
144
         session_log(session, "[cmd_copy_msg] Copied message %lu to %s",
145
                     msgno, mailbox);
146
         session->current = msgno;
147
@@ -162,9 +162,8 @@ void cmd_copy_msg(struct session *sessio
148
         return;
149
     }
150
 
151
-    session_message(session,
152
-                    "Copied message %lu to \"%s\", displaying %lu out of %lu",
153
-                    msgno, mailbox, next, zm->nmsgs);
154
+    session_message(session, "Copied message %lu to \"%s\", displaying %lu out of %lu",
155
+                    msgno, utf8_from_imaputf7(request->pool, mailbox), next, zm->nmsgs);
156
     session_log(session, "[cmd_copy_msg] Copied message %lu to %s",
157
                 msgno, mailbox);
158
 
159
Index: prayer-1.0.18/prayer/cmd_create.c
160
===================================================================
161
--- prayer-1.0.18.orig/prayer/cmd_create.c      2007-03-10 19:38:53.919358672 +0100
162
+++ prayer-1.0.18/prayer/cmd_create.c   2007-03-10 19:39:30.554075959 +0100
163
@@ -21,7 +21,8 @@ void cmd_create(struct session *session)
164
 
165
     request_decode_get(request);
166
 
167
-    if ((mailbox = assoc_lookup(request->form, "name")) == NIL) {
168
+    if ((mailbox = utf8_to_imaputf7(request->pool,
169
+                                    assoc_lookup(request->form, "name"))) == NIL) {
170
         session_redirect(session, request, "error");
171
         return;
172
     }
173
@@ -58,12 +59,13 @@ void cmd_create(struct session *session)
174
             if (ml_have_error()) {
175
                 session_message(session,
176
                                 "Failed to create directory: %s - %s",
177
-                                path, ml_errmsg());
178
+                                utf8_from_imaputf7(request->pool, path), ml_errmsg());
179
                 session_log(session,
180
                             "[cmd_create] Failed to create directory: %s",
181
                             path);
182
             } else {
183
-                session_message(session, "Created directory: %s", path);
184
+                session_message(session, "Created directory: %s",
185
+                                utf8_from_imaputf7(request->pool, path));
186
                 session_log(session,
187
                             "[cmd_create] Created directory: %s", path);
188
                 dircache_add(session->dircache, path, T);
189
@@ -72,12 +74,13 @@ void cmd_create(struct session *session)
190
             if (ml_have_error()) {
191
                 session_message(session,
192
                                 "Failed to create mailbox: %s - %s",
193
-                                path, ml_errmsg());
194
+                                utf8_from_imaputf7(request->pool, path), ml_errmsg());
195
                 session_log(session,
196
                             "[cmd_create] Failed to create mailbox: %s",
197
                             path);
198
             } else {
199
-                session_message(session, "Created mailbox: %s", path);
200
+                session_message(session, "Created mailbox: %s",
201
+                                utf8_from_imaputf7(request->pool, path));
202
                 session_log(session, "[cmd_create] Created mailbox: %s",
203
                             path);
204
                 dircache_add(session->dircache, path, NIL);
205
Index: prayer-1.0.18/prayer/cmd_dir_check.c
206
===================================================================
207
--- prayer-1.0.18.orig/prayer/cmd_dir_check.c   2007-03-10 19:38:53.979366397 +0100
208
+++ prayer-1.0.18/prayer/cmd_dir_check.c        2007-03-10 19:39:30.584079823 +0100
209
@@ -43,7 +43,7 @@ void cmd_dir_check(struct session *sessi
210
 
211
     session_message(session,
212
                     "Refreshed directory cache for directory \"%s\" at %s",
213
-                    session->cwd, current_time());
214
+                    utf8_from_imaputf7(request->pool, session->cwd), current_time());
215
     dircache_invalidate(session, session->cwd);
216
 
217
     if (request->argc >= 2)
218
Index: prayer-1.0.18/prayer/cmd_display.c
219
===================================================================
220
--- prayer-1.0.18.orig/prayer/cmd_display.c     2007-03-10 19:38:54.049375411 +0100
221
+++ prayer-1.0.18/prayer/cmd_display.c  2007-03-10 19:39:30.644087551 +0100
222
@@ -567,9 +567,11 @@ show_textpart(struct session *session, M
223
     struct request *request = session->request;
224
     struct buffer *b = request->write_buffer;
225
     char *init_msg, *decode_msg;
226
+    char *charset = "ISO-8859-1";
227
     unsigned long len;
228
     BODY *body = NIL;
229
     BOOL show_html = NIL;
230
+    PARAMETER *parameter;
231
 
232
     if (!(body = ml_body(session, stream, msgno, section)))
233
         return(NIL);
234
@@ -580,6 +582,13 @@ show_textpart(struct session *session, M
235
         return(NIL);
236
     }
237
 
238
+    for (parameter = body->parameter; parameter; parameter = parameter->next) {
239
+        if (strcasecmp(parameter->attribute, "charset") == 0) {
240
+            charset = parameter->value;
241
+            break;
242
+        }
243
+    }
244
+
245
     if (!(init_msg = ml_fetchbody(session, stream, msgno, section, &len)))
246
         return(NIL);
247
 
248
@@ -637,10 +646,10 @@ show_textpart(struct session *session, M
249
     if (show_html) {
250
         if (decode_msg == init_msg)
251
             decode_msg = strdup(init_msg);
252
-        html_secure(session, b, decode_msg);
253
+        html_secure(session, b, utf8_from_string(request->pool, charset, decode_msg, len));
254
     } else {
255
         bprintf(b, "<pre>" CRLF);
256
-        wrap_line_html(session, b, decode_msg, 80);
257
+        wrap_line_html(session, b, utf8_from_string(request->pool, charset, decode_msg, len), 80);
258
         bprintf(b, "</pre>" CRLF);
259
     }
260
 
261
Index: prayer-1.0.18/prayer/cmd_favourites.c
262
===================================================================
263
--- prayer-1.0.18.orig/prayer/cmd_favourites.c  2007-03-10 19:38:54.109383138 +0100
264
+++ prayer-1.0.18/prayer/cmd_favourites.c       2007-03-10 19:39:30.664090126 +0100
265
@@ -104,7 +104,7 @@ generate_directory_line(struct session *
266
     html_session_bprintf(session, b, "<a href=\"", "\">" CRLF,
267
                          "favourites?cwd=%s", name);
268
 
269
-    html_quote_string(b, dir);
270
+    html_quote_string(b, utf8_from_imaputf7(pool, dir));
271
     bprintf(b, "</a></td>" CRLF);
272
     bputs(b, "<td>&nbsp;</td>" CRLF);
273
     bputs(b, "<td>&nbsp;</td>" CRLF);
274
@@ -134,7 +134,7 @@ generate_favourite_folder_line(struct se
275
     bputs(b, "</td>" CRLF);
276
 
277
     bputs(b, "<td nowrap>" CRLF);
278
-    html_quote_string(b, folder);
279
+    html_quote_string(b, utf8_from_imaputf7(pool, folder));
280
     bputs(b, "</td>" CRLF);
281
 
282
     html_textlink_mailbox_table(session, b, "unsubscribe", name,
283
@@ -170,7 +170,7 @@ generate_folder_line(struct session *ses
284
     bputs(b, "</td>" CRLF);
285
 
286
     bprintf(b, "<td nowrap>" CRLF);
287
-    html_quote_string(b, folder);
288
+    html_quote_string(b, utf8_from_imaputf7(pool, folder));
289
     bprintf(b, "</td>" CRLF);
290
 
291
     html_textlink_mailbox_table(session, b, "subscribe", name,
292
@@ -208,8 +208,8 @@ html_folderlist(struct session *session,
293
         bputs(b, "<tr>");
294
     bputs(b, "<td>");
295
     bputs(b, "<table><tr><td>" CRLF);
296
-    html_form_field(b, "Directory", "cwd", session->cwd, 32);
297
-    html_form_field(b, "Filter", "filter", session->dir_filter, 12);
298
+    html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
299
+    html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
300
     html_form_submit(b, "submit", "Apply");
301
     bputs(b, "</td></tr></table>" CRLF);
302
     bputs(b, "</td>" CRLF);
303
Index: prayer-1.0.18/prayer/cmd_filter_select.c
304
===================================================================
305
--- prayer-1.0.18.orig/prayer/cmd_filter_select.c       2007-03-10 19:38:54.159389577 +0100
306
+++ prayer-1.0.18/prayer/cmd_filter_select.c    2007-03-10 19:39:30.694093991 +0100
307
@@ -68,7 +68,7 @@ generate_directory_line(struct session *
308
     html_session_bprintf(session, b, "<td><a href=\"", "\">" CRLF,
309
                          "filter_select?cwd=%s", name);
310
 
311
-    html_quote_string(b, dir);
312
+    html_quote_string(b, utf8_from_imaputf7(pool, dir));
313
     bprintf(b, "</a></td>" CRLF);
314
 
315
     bputs(b, "</tr>" CRLF);
316
@@ -93,7 +93,7 @@ generate_favourite_folder_line(struct se
317
     bputs(b, "</td>" CRLF);
318
 
319
     bputs(b, "<td>" CRLF);
320
-    html_quote_string(b, folder);
321
+    html_quote_string(b, utf8_from_imaputf7(pool, folder));
322
     bputs(b, "</td>" CRLF);
323
 
324
     html_textlink_mailbox_table(session, b, "filter_mbox/copy", name,
325
@@ -124,7 +124,7 @@ generate_folder_line(struct session *ses
326
     bputs(b, "</td>" CRLF);
327
 
328
     bputs(b, "<td>" CRLF);
329
-    html_quote_string(b, folder);
330
+    html_quote_string(b, utf8_from_imaputf7(pool, folder));
331
     bputs(b, "</td>" CRLF);
332
 
333
     html_textlink_mailbox_table(session, b, "filter_mbox/copy", name,
334
@@ -159,8 +159,8 @@ html_folderlist(struct session *session,
335
     /* Change directory form, including back button */
336
     html_form_start(session, b, "GET", "filter_select");
337
 
338
-    html_form_field(b, "Directory", "cwd", session->cwd, 32);
339
-    html_form_field(b, "Filter", "filter", session->dir_filter, 12);
340
+    html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
341
+    html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
342
     html_form_submit(b, "sub_apply", "Apply");
343
     html_form_submit(b, "sub_cancel", "Cancel");
344
     html_form_end(b);
345
Index: prayer-1.0.18/prayer/cmd_folders.c
346
===================================================================
347
--- prayer-1.0.18.orig/prayer/cmd_folders.c     2007-03-10 19:38:54.249401166 +0100
348
+++ prayer-1.0.18/prayer/cmd_folders.c  2007-03-10 19:39:30.734099143 +0100
349
@@ -95,7 +95,7 @@ generate_directory_line(struct session *
350
 
351
     html_session_bprintf(session, b, "<td><a href=\"", "\">" CRLF,
352
                          "folders?cwd=%s", name);
353
-    html_quote_string(b, dir);
354
+    html_quote_string(b, utf8_from_imaputf7(pool, dir));
355
     bprintf(b, "</a></td>" CRLF);
356
 
357
     html_textlink_mailbox_table(session, b, "rename", name, "Rename");
358
@@ -127,7 +127,7 @@ generate_folder_line(struct session *ses
359
     html_session_bprintf(session, b, "<td nowrap><a href=\"", "\">" CRLF,
360
                          "change/%s", name);
361
 
362
-    html_quote_string(b, folder);
363
+    html_quote_string(b, utf8_from_imaputf7(pool, folder));
364
     bprintf(b, "</a></td>" CRLF);
365
 
366
     if (strcmp(name, "INBOX") != 0) {
367
@@ -165,8 +165,8 @@ html_folderlist(struct session *session,
368
     else
369
         bputs(b, "<tr>");
370
     bputs(b, "<td><table><tr><td>" CRLF);
371
-    html_form_field(b, "Directory", "cwd", session->cwd, 32);
372
-    html_form_field(b, "Filter", "filter", session->dir_filter, 12);
373
+    html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
374
+    html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
375
     html_form_submit(b, "submit", "Apply");
376
     bputs(b, "</td></tr></table></td>" CRLF);
377
     bputs(b, "<td align=\"right\"><table><tr>" CRLF);
378
@@ -267,7 +267,7 @@ void cmd_folders(struct session *session
379
         request_decode_get(request);
380
         h = request->form;
381
 
382
-        if ((s = assoc_lookup(h, "cwd"))) {
383
+        if ((s = utf8_to_imaputf7(request->pool, assoc_lookup(h, "cwd")))) {
384
             string_canon_decode(s);
385
 
386
             if (string_filename_valid(s))
387
@@ -277,7 +277,7 @@ void cmd_folders(struct session *session
388
                                 "Path contained illegal characters");
389
         }
390
 
391
-        if ((s = assoc_lookup(h, "filter"))
392
+        if ((s = utf8_to_imaputf7(request->pool, assoc_lookup(h, "filter")))
393
             && (strcmp(s, session->dir_filter) != 0))
394
             string_strdup(&session->dir_filter, s);
395
     }
396
Index: prayer-1.0.18/prayer/cmd_forward1.c
397
===================================================================
398
--- prayer-1.0.18.orig/prayer/cmd_forward1.c    2007-03-10 19:38:54.309408891 +0100
399
+++ prayer-1.0.18/prayer/cmd_forward1.c 2007-03-10 19:39:30.744100430 +0100
400
@@ -157,6 +157,8 @@ add_text(struct session *session,
401
     char *init_msg, *decode_msg, *type;
402
     BODY *body = NIL;
403
     char *section = "1";
404
+    PARAMETER *parameter;
405
+    char *charset = "ISO-8859-1";
406
 
407
     if (!(text = ml_fetch_header(session, stream, msgno,
408
                                  NIL, hdrslist, &len, 0)))
409
@@ -204,6 +206,13 @@ add_text(struct session *session,
410
     } else
411
         section = "1";
412
 
413
+    for (parameter = body->parameter; parameter; parameter = parameter->next) {
414
+        if (strcasecmp(parameter->attribute, "charset") == 0) {
415
+            charset = parameter->value;
416
+            break;
417
+        }
418
+    }
419
+
420
     if (!(init_msg = ml_fetchbody(session, stream, msgno, section, &len)))
421
         return (NIL);
422
 
423
Index: prayer-1.0.18/prayer/cmd_list.c
424
===================================================================
425
--- prayer-1.0.18.orig/prayer/cmd_list.c        2007-03-10 19:38:54.379417906 +0100
426
+++ prayer-1.0.18/prayer/cmd_list.c     2007-03-10 19:39:30.794106870 +0100
427
@@ -143,7 +143,7 @@ cmd_list_toolbar_hdr(struct session *ses
428
     bputs(b, "</tr></table></td>" CRLF);
429
 
430
     bputs(b, "<td width=\"33%\" align=\"center\"><strong>\"");
431
-    html_quote_string(b, session->foldername);
432
+    html_quote_string(b, utf8_from_imaputf7(session->request->pool, session->foldername));
433
     bputs(b, "\" with ");
434
     bprintf(b, "%lu%s %s" CRLF, count, marked, messages);
435
     bputs(b, "</strong></td>" CRLF);
436
@@ -378,7 +378,7 @@ cmd_list_msg(struct session *session,
437
         (char *) rfc1522_decode(pool_alloc(request->pool, strlen(string)),
438
                                 strlen(string), string, NIL);
439
 
440
-    string = string_prune(request->pool, string, config->list_addr_maxlen);
441
+    string = utf8_prune(request->pool, string, config->list_addr_maxlen);
442
 
443
     if (use_to)
444
         string = pool_strcat(request->pool, "To: ", string);
445
@@ -400,7 +400,7 @@ cmd_list_msg(struct session *session,
446
             rfc1522_decode(pool_alloc(request->pool, strlen(string)),
447
                            strlen(string), string, NIL);
448
 
449
-        string = string_prune(request->pool, string,
450
+        string = utf8_prune(request->pool, string,
451
                               config->list_subject_maxlen);
452
     } else
453
         string = "(No subject)";
454
Index: prayer-1.0.18/prayer/cmd_preferred.c
455
===================================================================
456
--- prayer-1.0.18.orig/prayer/cmd_preferred.c   2007-03-10 19:38:54.429424344 +0100
457
+++ prayer-1.0.18/prayer/cmd_preferred.c        2007-03-10 19:39:30.824110733 +0100
458
@@ -22,7 +22,8 @@ void cmd_preferred(struct session *sessi
459
         if (string_filename_valid(name)) {
460
             favourite_preferred(fl, name);
461
             options->save = T;
462
-            session_message(session, "Making %s preferred folder", name);
463
+            session_message(session, "Making %s preferred folder",
464
+                            utf8_from_imaputf7(request->pool, name));
465
         } else
466
             session_message(session,
467
                             "String contained illegal characters");
468
Index: prayer-1.0.18/prayer/cmd_rename.c
469
===================================================================
470
--- prayer-1.0.18.orig/prayer/cmd_rename.c      2007-03-10 19:38:54.499433358 +0100
471
+++ prayer-1.0.18/prayer/cmd_rename.c   2007-03-10 19:39:30.844113310 +0100
472
@@ -63,7 +63,7 @@ generate_directory_line(struct session *
473
     bprintf(b, "</a></td>" CRLF);
474
     html_session_bprintf(session, b, "<td><a href=\"", "\">" CRLF,
475
                          "rename?cwd=%s", name);
476
-    html_quote_string(b, dir);
477
+    html_quote_string(b, utf8_from_imaputf7(pool, dir));
478
     bprintf(b, "</a></td></tr>" CRLF);
479
 }
480
 
481
@@ -84,7 +84,7 @@ generate_folder_line(struct session *ses
482
     html_icon(session, b, "dir.gif", "[mailbox]");
483
     bputs(b, "</a></td>" CRLF);
484
     bputs(b, "<td><a>" CRLF);
485
-    html_quote_string(b, folder);
486
+    html_quote_string(b, utf8_from_imaputf7(pool, folder));
487
     bputs(b, "</a></td></tr>" CRLF);
488
 }
489
 
490
@@ -107,7 +107,7 @@ rename_html_folderlist(struct session *s
491
     if (session->rename_foldername)
492
         bprintf(b,
493
                 "<h2 align=\"center\">Rename folder %s to ...</h2>" CRLF,
494
-                session->rename_foldername);
495
+                utf8_from_imaputf7(pool, session->rename_foldername));
496
 
497
     /* Change directory form, including back button */
498
     html_form_start(session, b, "GET", "rename");
499
@@ -118,8 +118,8 @@ rename_html_folderlist(struct session *s
500
     else
501
         bputs(b, "<tr>");
502
     bputs(b, "<td>" CRLF);
503
-    html_form_field(b, "Directory", "cwd", session->cwd, 32);
504
-    html_form_field(b, "Filter", "filter", session->dir_filter, 12);
505
+    html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
506
+    html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
507
     html_form_submit(b, "submit", "Apply");
508
     bputs(b, "</td></tr></table>" CRLF);
509
     html_form_end(b);
510
Index: prayer-1.0.18/prayer/cmd_rename_item.c
511
===================================================================
512
--- prayer-1.0.18.orig/prayer/cmd_rename_item.c 2007-03-10 19:38:54.569442372 +0100
513
+++ prayer-1.0.18/prayer/cmd_rename_item.c      2007-03-10 19:39:30.864115885 +0100
514
@@ -29,7 +29,7 @@ void cmd_rename_item(struct session *ses
515
     }
516
 
517
     if (!(session->rename_foldername &&
518
-          (newname = assoc_lookup(request->form, "name")))) {
519
+          (newname = utf8_to_imaputf7(pool, assoc_lookup(request->form, "name"))))) {
520
         session_redirect(session, request, "folders");
521
         return;
522
     }
523
@@ -70,11 +70,13 @@ void cmd_rename_item(struct session *ses
524
     if (ml_have_error()) {
525
         session_message(session,
526
                         "Failed to rename mailbox: %s - %s",
527
-                        session->rename_foldername, ml_errmsg());
528
+                        utf8_from_imaputf7(pool, session->rename_foldername),
529
+                                           ml_errmsg());
530
     } else {
531
         session_message(session,
532
                         "Renamed mailbox %s to be %s",
533
-                        session->rename_foldername, newname);
534
+                        utf8_from_imaputf7(pool, session->rename_foldername),
535
+                                           newname);
536
         dircache_rename(session->dircache, session->rename_foldername,
537
                         newname);
538
     }
539
Index: prayer-1.0.18/prayer/cmd_reply2.c
540
===================================================================
541
--- prayer-1.0.18.orig/prayer/cmd_reply2.c      2007-03-10 19:38:54.619448812 +0100
542
+++ prayer-1.0.18/prayer/cmd_reply2.c   2007-03-10 19:39:30.894119749 +0100
543
@@ -51,6 +51,8 @@ add_text(struct session *session, struct
544
     char *init_msg, *decode_msg, *type;
545
     unsigned long len;
546
     char *text, *s;
547
+    PARAMETER *parameter;
548
+    char *charset = "ISO-8859-1";
549
 
550
     if ((body = ml_body(session, stream, msgno, "1")) == NIL)
551
         return(NIL);
552
@@ -91,6 +93,13 @@ add_text(struct session *session, struct
553
         return(T);
554
     }
555
 
556
+    for (parameter = body->parameter; parameter; parameter = parameter->next) {
557
+        if (strcasecmp(parameter->attribute, "charset") == 0) {
558
+            charset = parameter->value;
559
+            break;
560
+        }
561
+    }
562
+
563
     /* Got a valid text section to display */
564
     if (!(init_msg=ml_fetchbody(session, stream, msgno, section, &len)))
565
         return(NIL);
566
@@ -133,11 +142,11 @@ add_text(struct session *session, struct
567
         struct buffer *b = buffer_create(pool, 8192);
568
         if (decode_msg == init_msg)
569
             decode_msg = strdup(init_msg);
570
-        html_secure_strip_all(b, decode_msg);
571
+        html_secure_strip_all(b, utf8_from_string(pool, charset, decode_msg, len));
572
 
573
         text = buffer_fetch(b, 0, buffer_size(b), NIL);
574
     } else
575
-        text = decode_msg;
576
+        text = utf8_from_string(pool, charset, decode_msg, len);
577
 
578
     bputs(b, ">");
579
     for (s = text; *s;) {
580
Index: prayer-1.0.18/prayer/cmd_rm.c
581
===================================================================
582
--- prayer-1.0.18.orig/prayer/cmd_rm.c  2007-03-10 19:38:54.669455249 +0100
583
+++ prayer-1.0.18/prayer/cmd_rm.c       2007-03-10 19:39:30.914122325 +0100
584
@@ -32,16 +32,20 @@ void cmd_rm(struct session *session)
585
         bprintf(b,
586
                 "<h2 align=\"center\">Confirm directory deletion: \"%s\"</h2>"
587
                 CRLF,
588
-                string_canon_decode(pool_strdup
589
-                                    (request->pool, request->argv[2])));
590
+                utf8_from_imaputf7(request->pool,
591
+                                   string_canon_decode(pool_strdup
592
+                                                       (request->pool,
593
+                                                        request->argv[2]))));
594
 
595
     } else {
596
         html_start(session, b, "Confirm Mail folder deletion");
597
         bprintf(b,
598
                 "<h2 align=\"center\">Confirm folder deletion: \"%s\"</h2>"
599
                 CRLF,
600
-                string_canon_decode(pool_strdup
601
-                                    (request->pool, request->argv[2])));
602
+                utf8_from_imaputf7(request->pool,
603
+                                   string_canon_decode(pool_strdup
604
+                                                       (request->pool,
605
+                                                        request->argv[2]))));
606
     }
607
 
608
     cmd = pool_printf(request->pool, "rm1/%s/%s",
609
Index: prayer-1.0.18/prayer/cmd_rm1.c
610
===================================================================
611
--- prayer-1.0.18.orig/prayer/cmd_rm1.c 2007-03-10 19:38:54.719461687 +0100
612
+++ prayer-1.0.18/prayer/cmd_rm1.c      2007-03-10 19:39:30.944126189 +0100
613
@@ -55,7 +55,7 @@ void cmd_rm1(struct session *session)
614
             session_message(session, "%s", ml_errmsg());        /* Includes name */
615
         } else {
616
             session_message(session, "Deleted directory: \"%s\"", mailbox);
617
-            dircache_delete(session->dircache, mailbox);
618
+            dircache_delete(session->dircache, utf8_from_imaputf7(request->pool, mailbox));
619
         }
620
     } else {
621
         ml_delete(session, stream,
622
@@ -67,7 +67,8 @@ void cmd_rm1(struct session *session)
623
         } else if (ml_have_error()) {
624
             session_message(session, "%s", ml_errmsg());        /* Includes name */
625
         } else {
626
-            session_message(session, "Deleted mailbox: \"%s\"", mailbox);
627
+            session_message(session, "Deleted mailbox: \"%s\"",
628
+                            utf8_from_imaputf7(request->pool, mailbox));
629
             dircache_delete(session->dircache, mailbox);
630
             if (favourite_delete(fl, mailbox))
631
                 options->save = T;
632
Index: prayer-1.0.18/prayer/cmd_subscribe.c
633
===================================================================
634
--- prayer-1.0.18.orig/prayer/cmd_subscribe.c   2007-03-10 19:38:54.769468126 +0100
635
+++ prayer-1.0.18/prayer/cmd_subscribe.c        2007-03-10 19:39:30.954127477 +0100
636
@@ -23,7 +23,7 @@ void cmd_subscribe(struct session *sessi
637
             if (favourite_add(fl, name)) {
638
                 options->save = T;
639
                 session_message(session, "Added %s to favourites list",
640
-                                name);
641
+                                utf8_from_imaputf7(request->pool, name));
642
             } else
643
                 session_message(session, "Already on favourites list",
644
                                 name);
645
Index: prayer-1.0.18/prayer/cmd_transfer.c
646
===================================================================
647
--- prayer-1.0.18.orig/prayer/cmd_transfer.c    2007-03-10 19:38:54.829475852 +0100
648
+++ prayer-1.0.18/prayer/cmd_transfer.c 2007-03-10 19:39:30.994132629 +0100
649
@@ -93,7 +93,7 @@ generate_directory_line(struct session *
650
     html_session_bprintf(session, b,
651
                          "<td><a href=\"", "\">" CRLF, "transfer?cwd=%s",
652
                          name);
653
-    html_quote_string(b, dir);
654
+    html_quote_string(b, utf8_from_imaputf7(pool, dir));
655
     bprintf(b, "</a></td>" CRLF);
656
 
657
     bputs(b, "<td>&nbsp;</td>" CRLF);
658
@@ -125,7 +125,7 @@ generate_favourite_folder_line(struct se
659
     bputs(b, "</a></td>" CRLF);
660
 
661
     bputs(b, "<td><a>" CRLF);
662
-    html_quote_string(b, folder);
663
+    html_quote_string(b, utf8_from_imaputf7(pool, folder));
664
     bputs(b, "</a></td>" CRLF);
665
 
666
     bprintf(b, "<td><a href=\"%s/NOSEQ/transfer/%s/%s\">" CRLF,
667
@@ -159,7 +159,7 @@ generate_folder_line(struct session *ses
668
     bputs(b, "</a></td>" CRLF);
669
 
670
     bputs(b, "<td>" CRLF);
671
-    html_quote_string(b, folder);
672
+    html_quote_string(b, utf8_from_imaputf7(pool, folder));
673
     bputs(b, "</td>" CRLF);
674
 
675
     bprintf(b, "<td><a href=\"%s/NOSEQ/transfer/%s/%s\">" CRLF,
676
@@ -197,8 +197,8 @@ html_folderlist(struct session *session,
677
     else
678
         bputs(b, "<tr>");
679
     bputs(b, "<td><table><tr><td>" CRLF);
680
-    html_form_field(b, "Directory", "cwd", session->cwd, 32);
681
-    html_form_field(b, "Filter", "filter", session->dir_filter, 12);
682
+    html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
683
+    html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
684
     html_form_submit(b, "submit", "Apply");
685
     bputs(b, "</td></tr></table></td>" CRLF);
686
     bputs(b, "<td align=\"right\"><table><tr><td>" CRLF);
687
@@ -332,7 +332,8 @@ static BOOL download(struct session *ses
688
                   OP_READONLY);
689
 
690
     if (!session->xfer_stream) {
691
-        session_message(session, "Failed to open mail folder: %s", name);
692
+        session_message(session, "Failed to open mail folder: %s",
693
+                        utf8_from_imaputf7(request->pool, name));
694
         session_log(session,
695
                     "[cmd_transfer] Failed to open mail folder: %s", name);
696
         return (NIL);
697
@@ -343,7 +344,7 @@ static BOOL download(struct session *ses
698
     /* Fetch overview for all messages in folder */
699
     if (!ml_fetch_overview(session, tstream, "1:*", NIL)) {
700
         session_message(session, "Failed to fetch folder overview: %s",
701
-                        name);
702
+                        utf8_from_imaputf7(request->pool, name));
703
         session_log(session,
704
                     "[cmd_transfer]] Failed to fetch overview: %s", name);
705
         return (NIL);
706
Index: prayer-1.0.18/prayer/cmd_unsubscribe.c
707
===================================================================
708
--- prayer-1.0.18.orig/prayer/cmd_unsubscribe.c 2007-03-10 19:38:54.919487442 +0100
709
+++ prayer-1.0.18/prayer/cmd_unsubscribe.c      2007-03-10 19:39:31.014135204 +0100
710
@@ -23,10 +23,11 @@ void cmd_unsubscribe(struct session *ses
711
             if (favourite_delete(fl, name)) {
712
                 options->save = T;
713
                 session_message(session, "Removed %s from favourites list",
714
-                                name);
715
+                                utf8_from_imaputf7(request->pool, name));
716
             } else
717
                 session_message(session,
718
-                                "Folder %s not on favourites list", name);
719
+                                "Folder %s not on favourites list",
720
+                                utf8_from_imaputf7(request->pool, name));
721
         } else
722
             session_message(session,
723
                             "String contained illegal characters");
724
Index: prayer-1.0.18/prayer/cmd_upload_select.c
725
===================================================================
726
--- prayer-1.0.18.orig/prayer/cmd_upload_select.c       2007-03-10 19:38:54.969493881 +0100
727
+++ prayer-1.0.18/prayer/cmd_upload_select.c    2007-03-10 19:39:31.034137781 +0100
728
@@ -122,8 +122,8 @@ html_folderlist(struct session *session,
729
 
730
     /* Change directory form, including back button */
731
     html_form_start(session, b, "GET", "upload_select");
732
-    html_form_field(b, "Directory", "cwd", session->cwd, 32);
733
-    html_form_field(b, "Filter", "filter", session->dir_filter, 12);
734
+    html_form_field(b, "Directory", "cwd", utf8_from_imaputf7(pool, session->cwd), 32);
735
+    html_form_field(b, "Filter", "filter", utf8_from_imaputf7(pool, session->dir_filter), 12);
736
     html_form_submit(b, "submit", "Apply");
737
     html_form_end(b);
738
 
739
Index: prayer-1.0.18/prayer/draft.c
740
===================================================================
741
--- prayer-1.0.18.orig/prayer/draft.c   2007-03-10 19:38:55.019500318 +0100
742
+++ prayer-1.0.18/prayer/draft.c        2007-03-10 19:39:31.074142931 +0100
743
@@ -477,7 +477,7 @@ void draft_update_body(struct draft *d, 
744
     } else
745
         d->body = pool_strdup(d->pool, d->body);
746
 
747
-    draft_transliterate_1252((unsigned char *)d->body);
748
+    /*draft_transliterate_1252((unsigned char *)d->body);*/
749
 }
750
 
751
 /* draft_update() ********************************************************
752
@@ -535,7 +535,7 @@ void draft_update(struct draft *d, struc
753
     else
754
         d->body = pool_maybe_strdup(d->pool, d->body);
755
 
756
-    draft_transliterate_1252((unsigned char *)d->body);
757
+    /*draft_transliterate_1252((unsigned char *)d->body);*/
758
 
759
     d->in_reply_to = pool_maybe_strdup(d->pool, d->in_reply_to);
760
     d->references  = pool_maybe_strdup(d->pool, d->references);
761
@@ -1164,7 +1164,7 @@ static void draft_make_multipart(struct 
762
     bprintf(b, CRLF "--%s" CRLF, cookie);
763
 
764
     bputs(b,
765
-          "Content-Type: text/plain; format=flowed; charset=ISO-8859-1"
766
+          "Content-Type: text/plain; format=flowed; charset=UTF-8"
767
           CRLF);
768
     if (need_qprint)
769
         bputs(b, "Content-Transfer-Encoding: QUOTED-PRINTABLE" CRLF);
770
@@ -1323,7 +1323,7 @@ static void draft_make_single_part(struc
771
         need_qprint = T;
772
 
773
     bputs(b,
774
-          "Content-Type: text/plain; format=flowed; charset=ISO-8859-1"
775
+          "Content-Type: text/plain; format=flowed; charset=UTF-8"
776
           CRLF);
777
     if (need_qprint)
778
         bputs(b, "Content-Transfer-Encoding: quoted-printable" CRLF);
779
@@ -1418,7 +1418,7 @@ char *draft_make_msg(struct draft *draft
780
 
781
         /* Encode using temporary buffer if required */
782
         s = (char *) rfc1522_encode(tmp, len,
783
-                                    (unsigned char *) s, "ISO-8859-1");
784
+                                    (unsigned char *) s, "UTF-8");
785
         bprintf(mb, "Subject: %s" CRLF, s);
786
         free(tmp);
787
     }
788
Index: prayer-1.0.18/prayer/html.c
789
===================================================================
790
--- prayer-1.0.18.orig/prayer/html.c    2007-03-10 19:38:55.069506757 +0100
791
+++ prayer-1.0.18/prayer/html.c 2007-03-10 19:39:31.134150660 +0100
792
@@ -35,7 +35,7 @@ void html_start(struct session *session,
793
         bprintf(b, "<title>Webmail service: %s</title>" CRLF, title);
794
     bputs(b, "<meta name=\"robots\" content=\"none\">" CRLF);
795
     bputs(b, ("<meta http-equiv=\"Content-Type\" "
796
-              "content=\"text/html; charset=ISO-8859-1\">" CRLF));
797
+              "content=\"text/html; charset=UTF-8\">" CRLF));
798
     bputs(b, "</head>" CRLF);
799
 
800
     bputs(b, "<body");
801
@@ -502,7 +502,7 @@ void
802
 html_form_start(struct session *s, struct buffer *b, char *method,
803
                 char *cmd)
804
 {
805
-    bprintf(b, "<form method=\"%s\" accept-charset=\"ISO-8859-1\"",
806
+    bprintf(b, "<form method=\"%s\" accept-charset=\"UTF-8\"",
807
             method);
808
     html_session_bputs(s, b, " action=\"", "\">" CRLF, cmd);
809
 }
810
@@ -854,7 +854,7 @@ html_banner_toolbar_favourites(struct se
811
                     string_canon_encode(request->pool, li->name));
812
         }
813
 
814
-        html_quote_string(b, li->name);
815
+        html_quote_string(b, utf8_from_imaputf7(request->pool, li->name));
816
         bputs(b, "</option>" CRLF);
817
     }
818
     bputs(b, "</select>" CRLF);
819
@@ -926,14 +926,14 @@ html_banner_toolbar_folders(struct sessi
820
         if (prefix) {
821
             bprintf(b, "<option value=\"%s%s\">",
822
                     prefix, string_canon_encode(request->pool, dl->name));
823
-            html_quote_string(b, session->cwd);
824
+            html_quote_string(b, utf8_from_imaputf7(request->pool, session->cwd));
825
             html_quote_string(b, "/");
826
-            html_quote_string(b, dl->name);
827
+            html_quote_string(b, utf8_from_imaputf7(request->pool, dl->name));
828
             bputs(b, "</option>" CRLF);
829
         } else if (strcasecmp(dl->name, "INBOX") != 0) {
830
             bprintf(b, "<option value=\"%s\">",
831
                     string_canon_encode(request->pool, dl->name));
832
-            html_quote_string(b, dl->name);
833
+            html_quote_string(b, utf8_from_imaputf7(request->pool, dl->name));
834
             bputs(b, "</option>" CRLF);
835
         }
836
     }
837
@@ -1077,7 +1077,8 @@ html_banner_toolbar(struct session *sess
838
 void html_quote_char(struct buffer *b, unsigned char c)
839
 {
840
     if (c > 127) {
841
-        bprintf(b, "&#%lu;", (unsigned long) c);
842
+      /*bprintf(b, "&#%lu;", (unsigned long) c);*/
843
+        bputc(b, c);
844
     } else
845
         switch (c) {
846
         case '"':
847
Index: prayer-1.0.18/prayer/prayer_session.h
848
===================================================================
849
--- prayer-1.0.18.orig/prayer/prayer_session.h  2007-03-10 19:39:29.243907238 +0100
850
+++ prayer-1.0.18/prayer/prayer_session.h       2007-03-10 19:39:31.844242104 +0100
851
@@ -74,3 +74,4 @@ extern int errno;               /* just 
852
 #include "checksum.h"
853
 #include "wrap.h"
854
 #include "portlist.h"
855
+#include "utf8.h"
856
Index: prayer-1.0.18/prayer/response.c
857
===================================================================
858
--- prayer-1.0.18.orig/prayer/response.c        2007-03-10 19:38:55.169519634 +0100
859
+++ prayer-1.0.18/prayer/response.c     2007-03-10 19:39:31.904249831 +0100
860
@@ -405,7 +405,7 @@ void response_error(struct request *requ
861
     bputs(b, "Expires: ");
862
     response_date_string(b, time(NIL));
863
     bputs(b, "" CRLF);
864
-    bprintf(b, "Content-Type: text/html; charset=iso-8859-1" CRLF);
865
+    bprintf(b, "Content-Type: text/html; charset=UTF-8" CRLF);
866
     bprintf(b, "Content-Length: %lu" CRLF,
867
             buffer_size(request->write_buffer));
868
     response_header_end(request);
869
@@ -437,7 +437,7 @@ void response_html(struct request *reque
870
 
871
     /* Generate simple header block for HTML */
872
     response_header_start(request, status);
873
-    bputs(b, "Content-Type: text/html; charset=iso-8859-1" CRLF);
874
+    bputs(b, "Content-Type: text/html; charset=UTF-8" CRLF);
875
 
876
 #ifdef STELLA_HACK
877
     bputs(b, "Expires: ");
878
Index: prayer-1.0.18/prayer/rfc1522.c
879
===================================================================
880
--- prayer-1.0.18.orig/prayer/rfc1522.c 2007-03-10 19:38:55.249529936 +0100
881
+++ prayer-1.0.18/prayer/rfc1522.c      2007-03-10 19:39:31.934253696 +0100
882
@@ -162,6 +162,7 @@ char **charset;
883
     unsigned char *rv = NULL, *p;
884
     char *start = s, *sw, *cset, *enc, *txt, *ew, **q, *lang;
885
     unsigned long l;
886
+    unsigned char *src;
887
     int i;
888
 
889
     *d = '\0';                  /* init destination */
890
@@ -171,15 +172,16 @@ char **charset;
891
     while (s && (sw = strstr(s, RFC1522_INIT))) {
892
         /* validate the rest of the encoded-word */
893
         if (rfc1522_valid(sw, &cset, &enc, &txt, &ew)) {
894
-            if (!rv)
895
+           if (!rv)
896
                 rv = d;         /* remember start of dest */
897
 
898
             /* copy everything between s and sw to destination */
899
             for (i = 0; &s[i] < sw; i++)
900
                 if (!isspace((unsigned char) s[i])) {   /* if some non-whitespace */
901
-                    while (s < sw && d - rv < len - 1)
902
-                        *d++ = (unsigned char) *s++;
903
-
904
+                    /* Assume that any 8 bit characters are Latin-1 */
905
+                    utf8_print(VAR_CHAR_SET, NULL,
906
+                               &d, len - (d - rv) - 1,
907
+                               (unsigned char**)&s, sw - s);
908
                     break;
909
                 }
910
 
911
@@ -188,23 +190,12 @@ char **charset;
912
             if ((lang = strchr(cset, '*')))
913
                 *lang++ = '\0';
914
 
915
-
916
-            /* Insert text explaining charset if we don't know what it is */
917
-            if ((strcasecmp((char *) cset, VAR_CHAR_SET))
918
-                && strcasecmp((char *) cset, "US-ASCII")) {
919
-                if (charset) {
920
-                    if (!*charset)      /* only write first charset */
921
-                        *charset = cpystr(cset);
922
-                } else {
923
-                    if (d - rv < len - 1)
924
-                        *d++ = '[';
925
-
926
-                    sstrncpy((char **) &d, cset, len - 1 - (d - rv));
927
-                    if (d - rv < len - 1)
928
-                        *d++ = ']';
929
-                    if (d - rv < len - 1)
930
-                        *d++ = SPACE;
931
-                }
932
+            if (!*cset) {
933
+                cset = UNKNOWN_CHARSET;
934
+            }
935
+            if (charset) {
936
+                if (!*charset)      /* only write first charset */
937
+                    *charset = cpystr(cset);
938
             }
939
 
940
             /* based on encoding, write the encoded text to output buffer */
941
@@ -228,15 +219,14 @@ char **charset;
942
                 } else
943
                     q = NULL;
944
 
945
-                if ((p =
946
+                if ((src = p =
947
                      rfc822_qprint((unsigned char *) txt, strlen(txt),
948
                                    &l))) {
949
-                    strncpy((char *) d, (char *) p, len - 1 - (d - rv));
950
-                    d[len - 1 - (d - rv)] = '\0';
951
+                    utf8_print(cset, VAR_CHAR_SET,
952
+                               &d, len - 1 - (d - rv),
953
+                               &src, l);
954
+                    *d = '\0';
955
                     fs_give((void **) &p);      /* free encoded buf */
956
-                    d += l;     /* advance dest ptr to EOL */
957
-                    if (d - rv > len - 1)
958
-                        d = rv + len - 1;
959
                 } else {
960
                     if (q)
961
                         fs_give((void **) &q);
962
@@ -255,22 +245,26 @@ char **charset;
963
 
964
             case 'B':          /* 'B' encoding */
965
             case 'b':
966
-                if ((p =
967
+                if ((src = p =
968
                      rfc822_base64((unsigned char *) txt, strlen(txt),
969
                                    &l))) {
970
-                    strncpy((char *) d, (char *) p, len - 1 - (d - rv));
971
-                    d[len - 1 - (d - rv)] = '\0';
972
+                    utf8_print(cset, VAR_CHAR_SET,
973
+                               &d, len - 1 - (d - rv),
974
+                               &src, l);
975
+                    *d = '\0';
976
                     fs_give((void **) &p);      /* free encoded buf */
977
-                    d += l;     /* advance dest ptr to EOL */
978
-                    if (d - rv > len - 1)
979
-                        d = rv + len - 1;
980
                 } else
981
                     goto bogus;
982
 
983
                 break;
984
 
985
+            bogus:
986
             default:
987
-                sstrncpy((char **) &d, txt, len - 1 - (d - rv));
988
+                src = txt;
989
+                utf8_print(VAR_CHAR_SET, NULL,
990
+                           &d, len - 1 - (d - rv),
991
+                           (unsigned char **)&src, ew - txt);
992
+               *d = '\0';
993
                 break;
994
             }
995
 
996
@@ -283,6 +277,7 @@ char **charset;
997
 
998
             if (lang)
999
                 lang[-1] = '*';
1000
+
1001
         } else {
1002
 
1003
             /*
1004
@@ -291,28 +286,38 @@ char **charset;
1005
 
1006
             /* if already copying to destn, copy it */
1007
             if (rv) {
1008
-                strncpy((char *) d, s,
1009
-                        (int) min((l = (sw - s) + RFC1522_INIT_L),
1010
-                                  len - 1 - (d - rv)));
1011
-                d += l;         /* advance d, tie off text */
1012
-                if (d - rv > len - 1)
1013
-                    d = rv + len - 1;
1014
+                utf8_print(VAR_CHAR_SET, NULL,
1015
+                           &d, len - 1 - (d - rv),
1016
+                           (unsigned char**)&s, sw - s);
1017
                 *d = '\0';
1018
-                s += l;         /* advance s beyond intro */
1019
             } else
1020
                 s += ((sw - s) + RFC1522_INIT_L);
1021
         }
1022
     }
1023
 
1024
-    if (rv && *s)               /* copy remaining text */
1025
-        strncat((char *) rv, s, len - 1 - strlen((char *) rv));
1026
+    if (rv && *s) {               /* copy remaining text */
1027
+        utf8_print(VAR_CHAR_SET, NULL,
1028
+                   &d, len - 1 - (d - rv),
1029
+                   (unsigned char**)&s, strlen(s));
1030
+        *d = '\0';
1031
+    }
1032
 
1033
 /* BUG: MUST do code page mapping under DOS after decoding */
1034
 
1035
-    return (rv ? rv : (unsigned char *) start);
1036
+    if (rv) return rv;
1037
+
1038
+    for (s = start; *s; s++) {
1039
+        if (*s & 0x80) {
1040
+            rv = d;
1041
+            utf8_print(VAR_CHAR_SET, NULL,
1042
+                       &d, len - 1,
1043
+                       (unsigned char**)&start, strlen(s));
1044
+            *d = '\0';
1045
+            return rv;
1046
 
1047
-  bogus:
1048
-    return ((unsigned char *) start);
1049
+        }
1050
+    }
1051
+    return (unsigned char *) start;
1052
 }
1053
 
1054
 
1055
@@ -364,7 +369,7 @@ int c;
1056
 int rfc1522_valenc(c)
1057
 int c;
1058
 {
1059
-    return (!(c == '?' || c == SPACE) && isprint((unsigned char) c));
1060
+    return (!(c == '?' /*|| c == SPACE*/) && isprint((unsigned char) c));
1061
 }
1062
 
1063
 
1064
@@ -386,7 +391,7 @@ char **endp;
1065
                        &e)
1066
         && rfc1522_token(++e, rfc1522_valtok, RFC1522_DLIM, &t)
1067
         && rfc1522_token(++t, rfc1522_valenc, RFC1522_TERM, &p)
1068
-        && p - s <= RFC1522_MAXW;
1069
+        /* && p - s <= RFC1522_MAXW */;
1070
 
1071
     if (charset)
1072
         *charset = c;
1073
Index: prayer-1.0.18/prayer/utf8.c
1074
===================================================================
1075
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
1076
+++ prayer-1.0.18/prayer/utf8.c 2007-03-10 19:39:31.974258848 +0100
1077
@@ -0,0 +1,418 @@
1078
+/* Copyright (c) Magnus Holmgren <magnus@kibibyte.se>,
1079
+ *                               <holmgren@lysator.liu.se>
1080
+ *
1081
+ * This file is free software; you can redistribute it and/or modify
1082
+ * it under the terms of the GNU General Public License as published by
1083
+ * the Free Software Foundation; either version 2 of the License, or
1084
+ * (at your option) any later version.
1085
+ *
1086
+ * This program is distributed in the hope that it will be useful,
1087
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1088
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1089
+ * GNU General Public License for more details.
1090
+ */
1091
+
1092
+#include "prayer_session.h"
1093
+#include <iconv.h>
1094
+
1095
+#define JNK 0177
1096
+#define UNI_REPLACEMENT_CHAR 0x0000FFFD
1097
+#define UNI_REPLACEMENT_CHAR_UTF8 "\xEF\xBF\xBD"
1098
+#define ICONV_CHUNK_SIZE 1024
1099
+
1100
+/* utf8_from_imaputf7() ***********************************************
1101
+ *
1102
+ * Convert a string encoded as modified UTF-7 to UTF-8.
1103
+ *       pool: Target pool for storage
1104
+ *          t: The string to convert
1105
+ *
1106
+ * Returns: A new, UTF-8-encoded string
1107
+ *
1108
+ * Note: This function tries hard to return something useful in case
1109
+ *       the input string is invalid in some way, rather than bail out
1110
+ *       and return NULL.
1111
+ **********************************************************************/
1112
+
1113
+char *utf8_from_imaputf7(struct pool *pool, char *t)
1114
+{
1115
+    struct buffer *b = buffer_create(pool, 64);
1116
+    BOOL base64mode = NIL;
1117
+    int i, j;
1118
+    unsigned char buf[4];
1119
+    unsigned char *s;
1120
+    unsigned long scalar; /* Unicode scalar value */
1121
+    unsigned char c;
1122
+
1123
+    static char decode_base64[256] = {
1124
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
1125
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
1126
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,076,077,JNK,JNK,JNK,
1127
+        064,065,066,067,070,071,072,073,074,075,JNK,JNK,JNK,JNK,JNK,JNK,
1128
+        JNK,000,001,002,003,004,005,006,007,010,011,012,013,014,015,016,
1129
+        017,020,021,022,023,024,025,026,027,030,031,JNK,JNK,JNK,JNK,JNK,
1130
+        JNK,032,033,034,035,036,037,040,041,042,043,044,045,046,047,050,
1131
+        051,052,053,054,055,056,057,060,061,062,063,JNK,JNK,JNK,JNK,JNK,
1132
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
1133
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
1134
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
1135
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
1136
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
1137
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
1138
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,
1139
+        JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK
1140
+    };
1141
+
1142
+    if (!t) return NULL;
1143
+
1144
+    for (s = (unsigned char*)t; *s; s++) {
1145
+        if (base64mode) {
1146
+            if (*s == '-') {
1147
+                if (j != 0 || c != 0) /* Some junk left */ {
1148
+                    bputs(b, UNI_REPLACEMENT_CHAR_UTF8);
1149
+                }
1150
+                base64mode = NIL;
1151
+                continue;
1152
+            }
1153
+
1154
+            if (decode_base64[*s] == JNK) {
1155
+                break;  /* Bail out */
1156
+            }
1157
+
1158
+            switch (i++) {
1159
+            case 0:
1160
+                /* Top 6 bits of the first octet */
1161
+                c = decode_base64[*s] << 2; break;
1162
+            case 1:
1163
+                /* Top 2 bits are bottom 2 bits of the first octet */
1164
+                buf[j++] = c | (decode_base64[*s] >> 4);
1165
+                /* and bottom 4 bits are top 4 bits of the second */
1166
+                c = decode_base64[*s] << 4; break;
1167
+            case 2:
1168
+                /* Top 4 bits are bottom 4 bits of the second octet */
1169
+                buf[j++] = c | (decode_base64[*s] >> 2);
1170
+                /* and bottom 2 bits are top 2 bits of the third */
1171
+                c = decode_base64[*s] << 6; break;
1172
+            case 3:
1173
+                /* Bottom 6 bits of the third octet */
1174
+                buf[j++] = c | decode_base64[*s];
1175
+                i = 0;
1176
+            }
1177
+
1178
+            /* Check if we have a complete UTF-16 character */
1179
+            if (j == 4) { /* We should now have a surrogate pair */
1180
+                scalar = ((buf[0] & 3) << 18) + (buf[1] << 10)
1181
+                    + ((buf[2] & 3) << 8) + buf[3] + 0x10000;
1182
+            }
1183
+            else if (j == 2) {
1184
+                if (buf[0] < 0xD8 || buf[0] > 0xDF) {
1185
+                    scalar = (buf[0] << 8) + buf[1];
1186
+                }
1187
+                else if (buf[0] > 0xDB) {
1188
+                    /* Error - invalid surrogate */
1189
+                    scalar = UNI_REPLACEMENT_CHAR;
1190
+                }
1191
+                else {
1192
+                    /* High surrogate found - need low surrogate */
1193
+                    continue;
1194
+                }
1195
+            }
1196
+            else continue; /* Odd number of bytes */
1197
+
1198
+            if (scalar >= 0x110000) scalar = UNI_REPLACEMENT_CHAR;
1199
+
1200
+            if (scalar < 0x80) {
1201
+                bputc(b, (unsigned char)scalar);
1202
+                j = 0;
1203
+                continue;
1204
+            } else if (scalar < 0x800) {
1205
+                bputc(b, 0xC0 | (scalar >> 6));
1206
+            } else if (scalar < 0x10000) {
1207
+                bputc(b, 0xE0 | (scalar >> 12));
1208
+            } else {
1209
+                bputc(b, 0xF0 | (scalar >> 18));
1210
+            }
1211
+
1212
+            if (scalar >= 0x10000)
1213
+                bputc(b, 0x80 | ((scalar >> 12) & 0x3F));
1214
+            if (scalar >= 0x800)
1215
+                bputc(b, 0x80 | ((scalar >> 6) & 0x3F));
1216
+            bputc(b, 0x80 | (scalar & 0x3F));
1217
+            j = 0;
1218
+
1219
+        }
1220
+        else /* !base64mode */ {
1221
+            if (*s == '&') {
1222
+                if (*(s+1) == '-') {
1223
+                    bputc(b, '&');
1224
+                    s++;
1225
+                }
1226
+                else {
1227
+                    base64mode = T;
1228
+                    i = 0; j = 0; c = 0;
1229
+                }
1230
+            }
1231
+            else {
1232
+                bputc(b, *s);
1233
+            }
1234
+        }
1235
+     }
1236
+     return buffer_fetch(b, 0, buffer_size(b), NIL);
1237
+}
1238
+
1239
+
1240
+/* utf8_to_imaputf7() *************************************************
1241
+ *
1242
+ * Convert a string encoded as UTF-8 to modified UTF-7.
1243
+ *       pool: Target pool for storage
1244
+ *          t: The string to convert
1245
+ *
1246
+ * Returns: A new string encoded as modified UTF-7
1247
+ *
1248
+ * Note: This function tries hard to return something useful in case
1249
+ *       the input string is invalid in some way, rather than bail out
1250
+ *       and return NULL.
1251
+ **********************************************************************/
1252
+
1253
+char *utf8_to_imaputf7(struct pool *pool, char *t)
1254
+{
1255
+    unsigned char *s;
1256
+    struct buffer *b = buffer_create(pool, 64);
1257
+    BOOL base64mode = NIL;
1258
+    unsigned long scalar;
1259
+    unsigned int L, i, j;
1260
+    unsigned char buf[4];
1261
+    unsigned char c = 0;
1262
+
1263
+    static char encode_base64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
1264
+    if (!t) return NULL;
1265
+
1266
+    for (s = (unsigned char *)t; *s; s++) {
1267
+        if (*s < 0x7f && *s >= 0x20) {
1268
+            if (base64mode) {
1269
+                switch (i) {
1270
+                case 1:
1271
+                    /* Remaining bottom 2 bits of the last octet */
1272
+                    bputc(b, encode_base64[c << 4]); break;
1273
+                case 2:
1274
+                    /* Remaining bottom 4 bits of the last octet */
1275
+                    bputc(b, encode_base64[c << 2]);
1276
+                }
1277
+                bputc(b, '-');
1278
+                base64mode = NIL;
1279
+            }
1280
+            bputc(b, *s);
1281
+            if (*s == '&') {
1282
+                bputc(b, '-');
1283
+            }
1284
+        }
1285
+        else {
1286
+            if (*s < 0x80) {
1287
+                L = 0; scalar = *s;
1288
+            } else if ((*s & 0xE0) == 0xC0) {
1289
+                L = 1; scalar = (*s & 0x1F);
1290
+            } else if ((*s & 0xF0) == 0xE0) {
1291
+                L = 2; scalar = (*s & 0x0F);
1292
+            } else if ((*s & 0xF8) == 0xF0) {
1293
+                L = 3; scalar = (*s & 0x07);
1294
+            } else if ((*s & 0xFC) == 0xF8) {
1295
+                L = 4; scalar = (*s & 0x03);
1296
+            } else if ((*s & 0xFE) == 0xFC) {
1297
+                L = 5; scalar = (*s & 0x01);
1298
+            } else {
1299
+                L = 0; scalar = UNI_REPLACEMENT_CHAR;
1300
+            }
1301
+
1302
+            for (j = 0; j < L; j++) {
1303
+                s++;
1304
+                if ((*s & 0xC0) == 0x80) {
1305
+                    scalar <<= 6;
1306
+                    scalar |= (*s & 0x3F);
1307
+                }
1308
+                else {
1309
+                    s--;
1310
+                    scalar = UNI_REPLACEMENT_CHAR;
1311
+                }
1312
+            }
1313
+
1314
+            if (!base64mode) {
1315
+                bputc(b, '&');
1316
+                base64mode = T;
1317
+                i = 0;
1318
+            }
1319
+            if (scalar <= 0xFFFF) {
1320
+                buf[1] = scalar & 0xFF;
1321
+                scalar >>= 8;
1322
+                buf[0] = scalar & 0xFF;
1323
+                L = 2;
1324
+            }
1325
+            else {
1326
+                scalar -= 0x100000UL;
1327
+                buf[3] = scalar & 0xFF;
1328
+                scalar >>= 8;
1329
+                buf[2] = 0xDC | (scalar & 0x03);
1330
+                scalar >>= 2;
1331
+                buf[3] = scalar & 0xFF;
1332
+                scalar >>= 8;
1333
+                buf[1] = 0xD8 | (scalar & 0x03);
1334
+                L = 4;
1335
+            }
1336
+
1337
+            for (j = 0; j < L; j++) {
1338
+                switch (i++) {
1339
+                case 0:
1340
+                    /* Top 6 bits of the first octet */
1341
+                    bputc(b, encode_base64[(buf[j] >> 2) & 0x3F]);
1342
+                    c = (buf[j] & 0x03); break;
1343
+                case 1:
1344
+                    /* Bottom 2 bits of the first octet, and top 4 bits of the second */
1345
+                    bputc(b, encode_base64[(c << 4) |
1346
+                                           ((buf[j] >> 4) & 0x0F)]);
1347
+                    c = (buf[j] & 0x0F); break;
1348
+                case 2:
1349
+                    /* Bottom 4 bits of the second octet and top 2 bits of the third */
1350
+                    bputc(b, encode_base64[(c << 2) |
1351
+                                           ((buf[j] >> 6) & 0x03)]);
1352
+                    /* Bottom 6 bits of the third octet */
1353
+                    bputc(b, encode_base64[buf[j] & 0x3F]);
1354
+                    i = 0;
1355
+                }
1356
+            }
1357
+
1358
+        }
1359
+    }
1360
+    if (base64mode) {
1361
+        switch (i) {
1362
+        case 1:
1363
+            /* Remaining bottom 2 bits of the last octet */
1364
+            bputc(b, encode_base64[c << 4]); break;
1365
+        case 2:
1366
+            /* Remaining bottom 4 bits of the last octet */
1367
+            bputc(b, encode_base64[c << 2]);
1368
+        }
1369
+        bputc(b, '-');
1370
+        base64mode = NIL;
1371
+    }
1372
+    return buffer_fetch(b, 0, buffer_size(b), NIL);
1373
+}
1374
+
1375
+
1376
+/* utf8_from_string() ************************************************
1377
+ *
1378
+ * Convert a string with given character encoding to UTF-8
1379
+ *
1380
+ *    pool: Pool to allocate memory from
1381
+ * charset: Charset of input string
1382
+ *       t: String to convert
1383
+ *     len: Length of string
1384
+ ***********************************************************************/
1385
+
1386
+char *utf8_from_string(struct pool *pool, char *charset, char *t, unsigned long len)
1387
+{
1388
+    struct buffer *b;
1389
+    char chunk[ICONV_CHUNK_SIZE];
1390
+    char *outbuf;
1391
+    size_t outbytesleft;
1392
+    size_t result;
1393
+    int i;
1394
+    iconv_t cd = iconv_open("UTF-8", charset);
1395
+    b = buffer_create(pool, 1024);
1396
+
1397
+    if (cd == (iconv_t)(-1)) {
1398
+        buffer_printf(b, "(Conversion from %s failed)", charset);
1399
+    }
1400
+    else while (len) {
1401
+        outbuf = chunk;
1402
+        outbytesleft = ICONV_CHUNK_SIZE;
1403
+        result = iconv(cd, &t, (size_t*)&len, &outbuf, &outbytesleft);
1404
+        for (i = 0; i < ICONV_CHUNK_SIZE - outbytesleft; i++) {
1405
+            bputc(b, chunk[i]);
1406
+        }
1407
+        if (result == (size_t)(-1)) switch (errno) {
1408
+        case E2BIG:
1409
+            break;
1410
+        case EILSEQ:
1411
+        case EINVAL:
1412
+            /* Try skipping a byte */
1413
+            t++;
1414
+            len--;
1415
+            bputs(b, UNI_REPLACEMENT_CHAR_UTF8);
1416
+            break;
1417
+        default:
1418
+            iconv_close(cd);
1419
+            return NULL;
1420
+        }
1421
+    }
1422
+
1423
+    iconv_close(cd);
1424
+    return buffer_fetch(b, 0, buffer_size(b), NIL);
1425
+}
1426
+
1427
+BOOL utf8_print(char *charset, char *fallback_charset,
1428
+                unsigned char **dst, unsigned long dst_size,
1429
+                unsigned char **src, unsigned long src_size)
1430
+{
1431
+
1432
+    iconv_t cd = iconv_open("UTF-8", charset);
1433
+    if (cd == (iconv_t)(-1) && fallback_charset)
1434
+        cd = iconv_open("UTF-8", fallback_charset);
1435
+
1436
+    while (iconv(cd, (char**)src, (size_t*)&src_size,
1437
+                     (char**)dst, (size_t*)&dst_size) == (size_t)(-1)) {
1438
+        switch (errno) {
1439
+        case EILSEQ:
1440
+        case EINVAL:
1441
+            /* Try skipping a byte */
1442
+            (*src)++;
1443
+            src_size--;
1444
+            if (dst_size >= sizeof(UNI_REPLACEMENT_CHAR_UTF8)) {
1445
+                strcpy((char*)*dst, UNI_REPLACEMENT_CHAR_UTF8);
1446
+            }
1447
+            if (errno == EILSEQ) break;
1448
+        case E2BIG:
1449
+        default:
1450
+            iconv_close(cd);
1451
+            return NIL;
1452
+        }
1453
+    }
1454
+    iconv_close(cd);
1455
+    return T;
1456
+}
1457
+
1458
+/* utf8_prune() ********************************************************
1459
+ *
1460
+ * Like string_prune, but counts UTF-8 multibyte sequences as units.
1461
+ *   pool: Target pool
1462
+ *      s: UTF-8 string to prune
1463
+ * maxlen: Maximum length of string before pruning applies.
1464
+ *
1465
+ * Returns: Pruned string, maximum maxlen characters (not bytes), not
1466
+ *          counting the terminating null.
1467
+ ***********************************************************************/
1468
+
1469
+char *utf8_prune(struct pool *pool, char *s, unsigned long maxlen)
1470
+{
1471
+    char *result;
1472
+    unsigned long cutoff;
1473
+    unsigned long L;
1474
+    unsigned long i = 0;
1475
+
1476
+    if (maxlen < (strlen("...") + 1))
1477
+        return (s);
1478
+
1479
+    for (L = 0; L < maxlen; L++) {
1480
+        if (s[i] == '\0') return s;
1481
+        if (L == maxlen - strlen("...")) cutoff = i;
1482
+
1483
+        if (s[i] & 0x80)
1484
+            while (s[i] & 0x80) i++;
1485
+        else
1486
+            i++;
1487
+    }
1488
+
1489
+    result = pool_alloc(pool, cutoff + 4);
1490
+    memcpy(result, s, cutoff);
1491
+    strcpy(result + cutoff, "...");
1492
+
1493
+    return (result);
1494
+
1495
+}
1496
Index: prayer-1.0.18/prayer/utf8.h
1497
===================================================================
1498
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
1499
+++ prayer-1.0.18/prayer/utf8.h 2007-03-10 19:39:32.004262711 +0100
1500
@@ -0,0 +1,7 @@
1501
+char *utf8_from_imaputf7(struct pool *pool, char *t);
1502
+char *utf8_to_imaputf7(struct pool *pool, char *t);
1503
+char *utf8_from_string(struct pool *pool, char *charset, char *t, unsigned long len);
1504
+BOOL utf8_print(char *charset, char *fallback_charset,
1505
+                unsigned char **dst, unsigned long dst_size,
1506
+                unsigned char **src, unsigned long src_size);
1507
+char *utf8_prune(struct pool *pool, char *s, unsigned long maxlen);