aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2002-01-19 08:03:05 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2002-01-19 08:03:05 +0800
commitda5d9e6dc27ff04ba3a571cdfbad6856297556cb (patch)
tree40ed654b0b93dac68571020a19e6813905350a57 /camel/providers/imap
parent695a0a631bd4fae44f5e3427d0ed166cd0a80f52 (diff)
downloadgsoc2013-evolution-da5d9e6dc27ff04ba3a571cdfbad6856297556cb.tar.gz
gsoc2013-evolution-da5d9e6dc27ff04ba3a571cdfbad6856297556cb.tar.zst
gsoc2013-evolution-da5d9e6dc27ff04ba3a571cdfbad6856297556cb.zip
New function to decode an IMAP mailbox name from modified UTF-7 encoding
2002-01-18 Jeffrey Stedfast <fejj@ximian.com> * providers/imap/camel-imap-utils.c (imap_mailbox_decode): New function to decode an IMAP mailbox name from modified UTF-7 encoding to UTF-8. (imap_mailbox_encode): New function to convert a mailbox name from UTF-8 to IMAP's modified UTF-7 encoding. svn path=/trunk/; revision=15361
Diffstat (limited to 'camel/providers/imap')
-rw-r--r--camel/providers/imap/camel-imap-utils.c264
-rw-r--r--camel/providers/imap/camel-imap-utils.h3
2 files changed, 266 insertions, 1 deletions
diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c
index 7d2073142b..746aec2167 100644
--- a/camel/providers/imap/camel-imap-utils.c
+++ b/camel/providers/imap/camel-imap-utils.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
+#include <iconv.h>
#include "camel-imap-utils.h"
#include "camel-imap-summary.h"
@@ -173,8 +174,10 @@ imap_parse_folder_name (CamelImapStore *store, const char *folder_name)
continue;
}
- if (*p == store->dir_sep)
+ if (*p == store->dir_sep) {
+ /* FIXME: decode mailbox */
g_ptr_array_add (heirarchy, g_strndup (folder_name, p - folder_name));
+ }
p++;
}
@@ -841,3 +844,262 @@ imap_namespace_concat (CamelImapStore *store, const char *name)
return imap_concat (store, store->namespace, name);
}
+
+
+#define UTF8_TO_UTF7_LEN(len) ((len * 3) + 8)
+#define UTF7_TO_UTF8_LEN(len) (len)
+
+enum {
+ MODE_USASCII,
+ MODE_AMPERSAND,
+ MODE_MODUTF7
+};
+
+#define is_usascii(c) (((c) >= 0x20 && (c) <= 0x25) || ((c) >= 0x27 && (c) <= 0x7e))
+#define encode_mode(c) (is_usascii (c) ? MODE_USASCII : (c) == '&' ? MODE_AMPERSAND : MODE_MODUTF7)
+
+char *
+imap_mailbox_encode (const unsigned char *in, int inlen)
+{
+ const unsigned char *start, *inptr, *inend;
+ unsigned char *mailbox, *m, *mend;
+ size_t inleft, outleft, conv;
+ char *inbuf, *outbuf;
+ iconv_t cd;
+ int mode;
+
+ cd = (iconv_t) -1;
+ m = mailbox = g_malloc (UTF8_TO_UTF7_LEN (inlen) + 1);
+ mend = mailbox + UTF8_TO_UTF7_LEN (inlen);
+
+ start = inptr = in;
+ inend = in + inlen;
+ mode = MODE_USASCII;
+
+ while (inptr < inend) {
+ int new_mode;
+
+ new_mode = encode_mode (*inptr);
+
+ if (new_mode != mode) {
+ switch (mode) {
+ case MODE_USASCII:
+ memcpy (m, start, inptr - start);
+ m += (inptr - start);
+ break;
+ case MODE_AMPERSAND:
+ while (start < inptr) {
+ *m++ = '&';
+ *m++ = '-';
+ start++;
+ }
+ break;
+ case MODE_MODUTF7:
+ inbuf = (char *) start;
+ inleft = inptr - start;
+ outbuf = (char *) m;
+ outleft = mend - m;
+
+ if (cd == (iconv_t) -1)
+ cd = iconv_open ("UTF-7", "UTF-8");
+
+ conv = iconv (cd, &inbuf, &inleft, &outbuf, &outleft);
+ if (conv == (size_t) -1) {
+ g_warning ("error converting mailbox to UTF-7!");
+ }
+ iconv (cd, NULL, NULL, &outbuf, &outleft);
+
+ /* shift into modified UTF-7 mode (overwrite UTF-7's '+' shift)... */
+ *m++ = '&';
+
+ while (m < (unsigned char *) outbuf) {
+ /* replace '/' with ',' */
+ if (*m == '/')
+ *m = ',';
+
+ m++;
+ }
+
+ break;
+ }
+
+ mode = new_mode;
+ start = inptr;
+ }
+
+ inptr++;
+ }
+
+ switch (mode) {
+ case MODE_USASCII:
+ memcpy (m, start, inptr - start);
+ m += (inptr - start);
+ break;
+ case MODE_AMPERSAND:
+ while (start < inptr) {
+ *m++ = '&';
+ *m++ = '-';
+ start++;
+ }
+ break;
+ case MODE_MODUTF7:
+ inbuf = (char *) start;
+ inleft = inptr - start;
+ outbuf = (char *) m;
+ outleft = mend - m;
+
+ if (cd == (iconv_t) -1)
+ cd = iconv_open ("UTF-7", "UTF-8");
+
+ conv = iconv (cd, &inbuf, &inleft, &outbuf, &outleft);
+ if (conv == (size_t) -1) {
+ g_warning ("error converting mailbox to UTF-7!");
+ }
+ iconv (cd, NULL, NULL, &outbuf, &outleft);
+
+ /* shift into modified UTF-7 mode (overwrite UTF-7's '+' shift)... */
+ *m++ = '&';
+
+ while (m < (unsigned char *) outbuf) {
+ /* replace '/' with ',' */
+ if (*m == '/')
+ *m = ',';
+
+ m++;
+ }
+
+ break;
+ }
+
+ *m = '\0';
+
+ if (cd != (iconv_t) -1)
+ iconv_close (cd);
+
+ return mailbox;
+}
+
+
+char *
+imap_mailbox_decode (const unsigned char *in, int inlen)
+{
+ const unsigned char *start, *inptr, *inend;
+ unsigned char *mailbox, *m, *mend;
+ unsigned char mode_switch;
+ iconv_t cd;
+
+ cd = (iconv_t) -1;
+ m = mailbox = g_malloc (UTF7_TO_UTF8_LEN (inlen) + 1);
+ mend = mailbox + UTF7_TO_UTF8_LEN (inlen);
+
+ start = inptr = in;
+ inend = in + inlen;
+ mode_switch = '&';
+
+ while (inptr < inend) {
+ if (*inptr == mode_switch) {
+ if (mode_switch == '&') {
+ /* mode switch from US-ASCII to UTF-7 */
+ mode_switch = '-';
+ memcpy (m, start, inptr - start);
+ m += (inptr - start);
+ start = inptr;
+ } else if (mode_switch == '-') {
+ /* mode switch from UTF-7 to US-ASCII or an ampersand (&) */
+ mode_switch = '&';
+ start++;
+ if (start == inptr) {
+ /* we had the sequence "&-" which becomes "&" when decoded */
+ *m++ = '&';
+ } else {
+ char *buffer, *inbuf, *outbuf;
+ size_t buflen, outleft, conv;
+
+ buflen = (inptr - start) + 2;
+ inbuf = buffer = alloca (buflen);
+ *inbuf++ = '+';
+ while (start < inptr) {
+ *inbuf++ = *start == ',' ? '/' : *start;
+ start++;
+ }
+ *inbuf = '-';
+
+ inbuf = buffer;
+ outbuf = (char *) m;
+ outleft = mend - m;
+
+ if (cd == (iconv_t) -1)
+ cd = iconv_open ("UTF-8", "UTF-7");
+
+ conv = iconv (cd, &inbuf, &buflen, &outbuf, &outleft);
+ if (conv == (size_t) -1) {
+ g_warning ("error decoding mailbox from UTF-7!");
+ }
+ iconv (cd, NULL, NULL, NULL, NULL);
+
+ m = (unsigned char *) outbuf;
+ }
+
+ /* point to the char after the '-' */
+ start = inptr + 1;
+ }
+ }
+
+ inptr++;
+ }
+
+ if (*inptr == mode_switch) {
+ if (mode_switch == '&') {
+ /* the remaining text is US-ASCII */
+ memcpy (m, start, inptr - start);
+ m += (inptr - start);
+ start = inptr;
+ } else if (mode_switch == '-') {
+ /* We've got encoded UTF-7 or else an ampersand */
+ start++;
+ if (start == inptr) {
+ /* we had the sequence "&-" which becomes "&" when decoded */
+ *m++ = '&';
+ } else {
+ char *buffer, *inbuf, *outbuf;
+ size_t buflen, outleft, conv;
+
+ buflen = (inptr - start) + 2;
+ inbuf = buffer = alloca (buflen);
+ *inbuf++ = '+';
+ while (start < inptr) {
+ *inbuf++ = *start == ',' ? '/' : *start;
+ start++;
+ }
+ *inbuf = '-';
+
+ inbuf = buffer;
+ outbuf = (char *) m;
+ outleft = mend - m;
+
+ if (cd == (iconv_t) -1)
+ cd = iconv_open ("UTF-8", "UTF-7");
+
+ conv = iconv (cd, &inbuf, &buflen, &outbuf, &outleft);
+ if (conv == (size_t) -1) {
+ g_warning ("error decoding mailbox from UTF-7!");
+ }
+ iconv (cd, NULL, NULL, NULL, NULL);
+
+ m = (unsigned char *) outbuf;
+ }
+ }
+ } else {
+ /* illegal encoded mailbox... */
+ g_warning ("illegal mailbox name encountered!");
+ memcpy (m, start, inptr - start);
+ m += (inptr - start);
+ }
+
+ *m = '\0';
+
+ if (cd != (iconv_t) -1)
+ iconv_close (cd);
+
+ return mailbox;
+}
diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h
index f64d56743a..bedc604116 100644
--- a/camel/providers/imap/camel-imap-utils.h
+++ b/camel/providers/imap/camel-imap-utils.h
@@ -72,6 +72,9 @@ void imap_uid_array_free (GPtrArray *arr);
char *imap_concat (CamelImapStore *imap_store, const char *prefix, const char *suffix);
char *imap_namespace_concat (CamelImapStore *store, const char *name);
+char *imap_mailbox_encode (const unsigned char *in, int inlen);
+char *imap_mailbox_decode (const unsigned char *in, int inlen);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */