From e64d8d322d85355b6c02ca725f5bd913a44459ad Mon Sep 17 00:00:00 2001 From: bagyenda <> Date: Mon, 29 Nov 2010 12:30:03 +0000 Subject: [PATCH] Added improved encoding of charsets in mm1 --- mbuni/ChangeLog | 2 + mbuni/mmlib/charmibenum.def | 340 ++++++++++++++++++++++++++++++++++++ mbuni/mmlib/mms_mm7soap.c | 10 +- mbuni/mmlib/mms_msg.c | 20 ++- mbuni/mmlib/mms_queue.c | 12 +- mbuni/mmlib/mms_util.c | 194 +++++++++++++++++++- mbuni/mmlib/mms_util.h | 12 ++ 7 files changed, 578 insertions(+), 12 deletions(-) create mode 100644 mbuni/mmlib/charmibenum.def diff --git a/mbuni/ChangeLog b/mbuni/ChangeLog index 910e881..159c450 100644 --- a/mbuni/ChangeLog +++ b/mbuni/ChangeLog @@ -1,3 +1,5 @@ +2010-11-29 P. A. Bagyenda + * Add better handling of character sets in mms fields 2010-11-26 P. A. Bagyenda * Minor fix for default log level (thanks to Piotr Isajew (pki at ex.com.pl) 2010-11-23 P. A. Bagyenda diff --git a/mbuni/mmlib/charmibenum.def b/mbuni/mmlib/charmibenum.def new file mode 100644 index 0000000..0521e93 --- /dev/null +++ b/mbuni/mmlib/charmibenum.def @@ -0,0 +1,340 @@ +/* + * Mbuni - Open Source MMS Gateway + * + * Charset MIBenum assignments - pre-processor magic. + * + * Copyright (C) 2003 - , Digital Solutions Ltd. - http://www.dsmagic.com + * + * Paul Bagyenda + * + * This program is free software, distributed under the terms of + * the GNU General Public License, with a few exceptions granted (see LICENSE) + */ + +#if !defined(CharMIBEnum) +#error "Required macro CharMIBEnum is missing." +#endif + +CharMIBEnum(3,ASCII) +CharMIBEnum(3,ANSI_X3.4-1968) +CharMIBEnum(3,ANSI_X3.4-1986) +CharMIBEnum(3,CP367) +CharMIBEnum(3,IBM367) +CharMIBEnum(3,ISO-IR-6) +CharMIBEnum(3,ISO646-US) +CharMIBEnum(3,ISO_646.IRV:1991) +CharMIBEnum(3,US) +CharMIBEnum(3,US-ASCII) +CharMIBEnum(3,CSASCII) +CharMIBEnum(4,CP819) +CharMIBEnum(4,IBM819) +CharMIBEnum(4,ISO-8859-1) +CharMIBEnum(4,ISO-IR-100) +CharMIBEnum(4,ISO8859-1) +CharMIBEnum(4,ISO_8859-1) +CharMIBEnum(4,ISO_8859-1:1987) +CharMIBEnum(4,L1) +CharMIBEnum(4,LATIN1) +CharMIBEnum(4,CSISOLATIN1) +CharMIBEnum(5,ISO-8859-2) +CharMIBEnum(5,ISO-IR-101) +CharMIBEnum(5,ISO8859-2) +CharMIBEnum(5,ISO_8859-2) +CharMIBEnum(5,ISO_8859-2:1987) +CharMIBEnum(5,L2) +CharMIBEnum(5,LATIN2) +CharMIBEnum(5,CSISOLATIN2) +CharMIBEnum(6,ISO-8859-3) +CharMIBEnum(6,ISO-IR-109) +CharMIBEnum(6,ISO8859-3) +CharMIBEnum(6,ISO_8859-3) +CharMIBEnum(6,ISO_8859-3:1988) +CharMIBEnum(6,L3) +CharMIBEnum(6,LATIN3) +CharMIBEnum(6,CSISOLATIN3) +CharMIBEnum(7,ISO-8859-4) +CharMIBEnum(7,ISO-IR-110) +CharMIBEnum(7,ISO8859-4) +CharMIBEnum(7,ISO_8859-4) +CharMIBEnum(7,ISO_8859-4:1988) +CharMIBEnum(7,L4) +CharMIBEnum(7,LATIN4) +CharMIBEnum(7,CSISOLATIN4) +CharMIBEnum(8,CYRILLIC) +CharMIBEnum(8,ISO-8859-5) +CharMIBEnum(8,ISO-IR-144) +CharMIBEnum(8,ISO8859-5) +CharMIBEnum(8,ISO_8859-5) +CharMIBEnum(8,ISO_8859-5:1988) +CharMIBEnum(8,CSISOLATINCYRILLIC) +CharMIBEnum(9,ARABIC) +CharMIBEnum(9,ASMO-708) +CharMIBEnum(9,ECMA-114) +CharMIBEnum(9,ISO-8859-6) +CharMIBEnum(9,ISO-IR-127) +CharMIBEnum(9,ISO8859-6) +CharMIBEnum(9,ISO_8859-6) +CharMIBEnum(9,ISO_8859-6:1987) +CharMIBEnum(9,CSISOLATINARABIC) +CharMIBEnum(10,ECMA-118) +CharMIBEnum(10,ELOT_928) +CharMIBEnum(10,GREEK) +CharMIBEnum(10,GREEK8) +CharMIBEnum(10,ISO-8859-7) +CharMIBEnum(10,ISO-IR-126) +CharMIBEnum(10,ISO8859-7) +CharMIBEnum(10,ISO_8859-7) +CharMIBEnum(10,ISO_8859-7:1987) +CharMIBEnum(10,ISO_8859-7:2003) +CharMIBEnum(10,CSISOLATINGREEK) +CharMIBEnum(11,HEBREW) +CharMIBEnum(11,ISO-8859-8) +CharMIBEnum(11,ISO-IR-138) +CharMIBEnum(11,ISO8859-8) +CharMIBEnum(11,ISO_8859-8) +CharMIBEnum(11,ISO_8859-8:1988) +CharMIBEnum(11,CSISOLATINHEBREW) +CharMIBEnum(12,ISO-8859-9) +CharMIBEnum(12,ISO-IR-148) +CharMIBEnum(12,ISO8859-9) +CharMIBEnum(12,ISO_8859-9) +CharMIBEnum(12,ISO_8859-9:1989) +CharMIBEnum(12,L5) +CharMIBEnum(12,LATIN5) +CharMIBEnum(12,CSISOLATIN5) +CharMIBEnum(13,ISO-8859-10) +CharMIBEnum(13,ISO-IR-157) +CharMIBEnum(13,ISO8859-10) +CharMIBEnum(13,ISO_8859-10) +CharMIBEnum(13,ISO_8859-10:1992) +CharMIBEnum(13,L6) +CharMIBEnum(13,LATIN6) +CharMIBEnum(13,CSISOLATIN6) +CharMIBEnum(15,JISX0201-1976) +CharMIBEnum(15,JIS_X0201) +CharMIBEnum(15,X0201) +CharMIBEnum(15,CSHALFWIDTHKATAKANA) +CharMIBEnum(17,MS_KANJI) +CharMIBEnum(17,SHIFT-JIS) +CharMIBEnum(17,SHIFT_JIS) +CharMIBEnum(17,SJIS) +CharMIBEnum(17,CSSHIFTJIS) +CharMIBEnum(17,SHIFT_JIS-2004) +CharMIBEnum(17,SHIFT_JISX0213) +CharMIBEnum(18,EUC-JP) +CharMIBEnum(18,EUCJP) +CharMIBEnum(18,EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE) +CharMIBEnum(18,CSEUCPKDFMTJAPANESE) +CharMIBEnum(36,ISO-IR-149) +CharMIBEnum(36,KOREAN) +CharMIBEnum(36,KSC_5601) +CharMIBEnum(36,KS_C_5601-1987) +CharMIBEnum(36,KS_C_5601-1989) +CharMIBEnum(36,CSKSC56011987) +CharMIBEnum(37,ISO-2022-KR) +CharMIBEnum(37,CSISO2022KR) +CharMIBEnum(38,EUC-KR) +CharMIBEnum(38,EUCKR) +CharMIBEnum(38,CSEUCKR) +CharMIBEnum(39,ISO-2022-JP) +CharMIBEnum(39,CSISO2022JP) +CharMIBEnum(39,ISO-2022-JP-1) +CharMIBEnum(39,ISO-2022-JP-2) +CharMIBEnum(39,CSISO2022JP2) +CharMIBEnum(39,ISO-2022-JP-2004) +CharMIBEnum(39,ISO-2022-JP-3) +CharMIBEnum(40,ISO-2022-JP-2) +CharMIBEnum(40,CSISO2022JP2) +CharMIBEnum(40,ISO-2022-JP-2004) +CharMIBEnum(40,ISO-2022-JP-3) +CharMIBEnum(42,ISO-IR-14) +CharMIBEnum(42,ISO646-JP) +CharMIBEnum(42,JIS_C6220-1969-RO) +CharMIBEnum(42,JP) +CharMIBEnum(42,CSISO14JISC6220RO) +CharMIBEnum(56,CN) +CharMIBEnum(56,GB_1988-80) +CharMIBEnum(56,ISO-IR-57) +CharMIBEnum(56,ISO646-CN) +CharMIBEnum(56,CSISO57GB1988) +CharMIBEnum(57,CHINESE) +CharMIBEnum(57,GB_2312-80) +CharMIBEnum(57,ISO-IR-58) +CharMIBEnum(57,CSISO58GB231280) +CharMIBEnum(63,ISO-IR-87) +CharMIBEnum(63,JIS0208) +CharMIBEnum(63,JIS_C6226-1983) +CharMIBEnum(63,JIS_X0208) +CharMIBEnum(63,JIS_X0208-1983) +CharMIBEnum(63,JIS_X0208-1990) +CharMIBEnum(63,X0208) +CharMIBEnum(63,CSISO87JISX0208) +CharMIBEnum(98,ISO-IR-159) +CharMIBEnum(98,JIS_X0212) +CharMIBEnum(98,JIS_X0212-1990) +CharMIBEnum(98,JIS_X0212.1990-0) +CharMIBEnum(98,X0212) +CharMIBEnum(98,CSISO159JISX02121990) +CharMIBEnum(103,UNICODE-1-1-UTF-7) +CharMIBEnum(103,UTF-7) +CharMIBEnum(103,CSUNICODE11UTF7) +CharMIBEnum(104,ISO-2022-CN) +CharMIBEnum(104,CSISO2022CN) +CharMIBEnum(104,ISO-2022-CN-EXT) +CharMIBEnum(105,ISO-2022-CN-EXT) +CharMIBEnum(106,UTF-8) +CharMIBEnum(106,UTF-8-MAC) +CharMIBEnum(106,UTF8-MAC) +CharMIBEnum(109,ISO-8859-13) +CharMIBEnum(109,ISO-IR-179) +CharMIBEnum(109,ISO8859-13) +CharMIBEnum(109,ISO_8859-13) +CharMIBEnum(109,L7) +CharMIBEnum(109,LATIN7) +CharMIBEnum(110,ISO-8859-14) +CharMIBEnum(110,ISO-CELTIC) +CharMIBEnum(110,ISO-IR-199) +CharMIBEnum(110,ISO8859-14) +CharMIBEnum(110,ISO_8859-14) +CharMIBEnum(110,ISO_8859-14:1998) +CharMIBEnum(110,L8) +CharMIBEnum(110,LATIN8) +CharMIBEnum(111,ISO-8859-15) +CharMIBEnum(111,ISO-IR-203) +CharMIBEnum(111,ISO8859-15) +CharMIBEnum(111,ISO_8859-15) +CharMIBEnum(111,ISO_8859-15:1998) +CharMIBEnum(111,LATIN-9) +CharMIBEnum(112,ISO-8859-16) +CharMIBEnum(112,ISO-IR-226) +CharMIBEnum(112,ISO8859-16) +CharMIBEnum(112,ISO_8859-16) +CharMIBEnum(112,ISO_8859-16:2001) +CharMIBEnum(112,L10) +CharMIBEnum(112,LATIN10) +CharMIBEnum(113,GBK) +CharMIBEnum(114,GB18030) +CharMIBEnum(1000,ISO-10646-UCS-2) +CharMIBEnum(1000,UCS-2) +CharMIBEnum(1000,CSUNICODE) +CharMIBEnum(1001,ISO-10646-UCS-4) +CharMIBEnum(1001,UCS-4) +CharMIBEnum(1001,CSUCS4) +CharMIBEnum(1010,UCS-2BE) +CharMIBEnum(1010,UNICODE-1-1) +CharMIBEnum(1010,UNICODEBIG) +CharMIBEnum(1010,CSUNICODE11) +CharMIBEnum(1010,UNICODE-1-1-UTF-7) +CharMIBEnum(1010,UTF-7) +CharMIBEnum(1010,CSUNICODE11UTF7) +CharMIBEnum(1012,UNICODE-1-1-UTF-7) +CharMIBEnum(1012,UTF-7) +CharMIBEnum(1012,CSUNICODE11UTF7) +CharMIBEnum(1013,UTF-16BE) +CharMIBEnum(1014,UTF-16LE) +CharMIBEnum(1015,UTF-16) +CharMIBEnum(1015,UTF-16BE) +CharMIBEnum(1015,UTF-16LE) +CharMIBEnum(1017,UTF-32) +CharMIBEnum(1017,UTF-32BE) +CharMIBEnum(1017,UTF-32LE) +CharMIBEnum(1018,UTF-32BE) +CharMIBEnum(1019,UTF-32LE) +CharMIBEnum(2004,HP-ROMAN8) +CharMIBEnum(2004,R8) +CharMIBEnum(2004,ROMAN8) +CharMIBEnum(2004,CSHPROMAN8) +CharMIBEnum(2009,850) +CharMIBEnum(2009,CP850) +CharMIBEnum(2009,IBM850) +CharMIBEnum(2009,CSPC850MULTILINGUAL) +CharMIBEnum(2013,862) +CharMIBEnum(2013,CP862) +CharMIBEnum(2013,IBM862) +CharMIBEnum(2013,CSPC862LATINHEBREW) +CharMIBEnum(2025,CHINESE) +CharMIBEnum(2025,GB_2312-80) +CharMIBEnum(2025,ISO-IR-58) +CharMIBEnum(2025,CSISO58GB231280) +CharMIBEnum(2025,CN-GB) +CharMIBEnum(2025,EUC-CN) +CharMIBEnum(2025,EUCCN) +CharMIBEnum(2025,GB2312) +CharMIBEnum(2025,CSGB2312) +CharMIBEnum(2026,BIG-5) +CharMIBEnum(2026,BIG-FIVE) +CharMIBEnum(2026,BIG5) +CharMIBEnum(2026,BIGFIVE) +CharMIBEnum(2026,CN-BIG5) +CharMIBEnum(2026,CSBIG5) +CharMIBEnum(2026,BIG5-HKSCS:1999) +CharMIBEnum(2026,BIG5-HKSCS:2001) +CharMIBEnum(2026,BIG5-HKSCS) +CharMIBEnum(2026,BIG5-HKSCS:2004) +CharMIBEnum(2026,BIG5HKSCS) +CharMIBEnum(2026,BIG5-2003) +CharMIBEnum(2027,MAC) +CharMIBEnum(2027,MACINTOSH) +CharMIBEnum(2027,MACROMAN) +CharMIBEnum(2027,CSMACINTOSH) +CharMIBEnum(2082,VISCII) +CharMIBEnum(2082,VISCII1.1-1) +CharMIBEnum(2082,CSVISCII) +CharMIBEnum(2084,KOI8-R) +CharMIBEnum(2084,CSKOI8R) +CharMIBEnum(2084,KOI8-RU) +CharMIBEnum(2085,HZ) +CharMIBEnum(2085,HZ-GB-2312) +CharMIBEnum(2086,866) +CharMIBEnum(2086,CP866) +CharMIBEnum(2086,IBM866) +CharMIBEnum(2086,CSIBM866) +CharMIBEnum(2088,KOI8-U) +CharMIBEnum(2101,BIG5-HKSCS:1999) +CharMIBEnum(2101,BIG5-HKSCS:2001) +CharMIBEnum(2101,BIG5-HKSCS) +CharMIBEnum(2101,BIG5-HKSCS:2004) +CharMIBEnum(2101,BIG5HKSCS) +CharMIBEnum(2103,CP154) +CharMIBEnum(2103,CYRILLIC-ASIAN) +CharMIBEnum(2103,PT154) +CharMIBEnum(2103,PTCP154) +CharMIBEnum(2103,CSPTCP154) +CharMIBEnum(2109,CP874) +CharMIBEnum(2109,WINDOWS-874) +CharMIBEnum(2250,CP1250) +CharMIBEnum(2250,MS-EE) +CharMIBEnum(2250,WINDOWS-1250) +CharMIBEnum(2251,CP1251) +CharMIBEnum(2251,MS-CYRL) +CharMIBEnum(2251,WINDOWS-1251) +CharMIBEnum(2252,CP1252) +CharMIBEnum(2252,MS-ANSI) +CharMIBEnum(2252,WINDOWS-1252) +CharMIBEnum(2253,CP1253) +CharMIBEnum(2253,MS-GREEK) +CharMIBEnum(2253,WINDOWS-1253) +CharMIBEnum(2254,CP1254) +CharMIBEnum(2254,MS-TURK) +CharMIBEnum(2254,WINDOWS-1254) +CharMIBEnum(2255,CP1255) +CharMIBEnum(2255,MS-HEBR) +CharMIBEnum(2255,WINDOWS-1255) +CharMIBEnum(2256,CP1256) +CharMIBEnum(2256,MS-ARAB) +CharMIBEnum(2256,WINDOWS-1256) +CharMIBEnum(2257,CP1257) +CharMIBEnum(2257,WINBALTRIM) +CharMIBEnum(2257,WINDOWS-1257) +CharMIBEnum(2258,CP1258) +CharMIBEnum(2258,WINDOWS-1258) +CharMIBEnum(2259,ISO-IR-166) +CharMIBEnum(2259,TIS-620) +CharMIBEnum(2259,TIS620) +CharMIBEnum(2259,TIS620-0) +CharMIBEnum(2259,TIS620.2529-1) +CharMIBEnum(2259,TIS620.2533-0) +CharMIBEnum(2259,TIS620.2533-1) + +#undef CharMIBEnum + diff --git a/mbuni/mmlib/mms_mm7soap.c b/mbuni/mmlib/mms_mm7soap.c index a17ec64..1b0199a 100644 --- a/mbuni/mmlib/mms_mm7soap.c +++ b/mbuni/mmlib/mms_mm7soap.c @@ -370,14 +370,16 @@ static int append_address(Octstr *p, Octstr *addr_spec, char *prefix, int add_ty { Octstr *v = addr_spec, *z; char *y, *typ = ""; + int j, ch = octstr_get_char(v, 0); if (ch == '-') y = " displayOnly=\"true\""; else y = ""; j = octstr_case_search(v, octstr_imm("/TYPE=PLMN"),0); - if (j >= 0 && octstr_search_char(v, '@', 0) < 0) { /* NO '@' */ - z = octstr_copy(v, 2, j-2); /* skip the initial char that is only for info purposes. */ + if ((j >= 0 || isphonenum_ex(v, 2)) && + octstr_search_char(v, '@', 0) < 0) { /* NO '@' */ + z = j>=0 ? octstr_copy(v, 2, j-2) : octstr_copy(v, 2, octstr_len(v)); /* skip the initial char that is only for info purposes. */ typ = octstr_len(z) <= 6 ? "ShortCode" : "Number"; } else { z = octstr_copy(v, 2, octstr_len(v)); @@ -814,7 +816,7 @@ int mm7_get_envelope(MSoapMsg_t *m, if ((s = http_header_value(m->envelope, octstr_imm("SenderAddress"))) == NULL) s = http_header_value(m->envelope, octstr_imm("Sender")); - if (s && octstr_get_char(s, 0) == '+') + if (s && (octstr_get_char(s, 0) == '+')) octstr_delete(s, 0, 2); else if (s) { octstr_destroy(s); @@ -954,7 +956,7 @@ MmsMsg *mm7_soap_to_mmsmsg(MSoapMsg_t *m, Octstr *from) } if ((f = http_header_value(m->envelope, octstr_imm("From"))) != NULL && - octstr_get_char(f, 0) == '+') + (octstr_get_char(f, 0) == '+')) octstr_delete(f, 0, 2); else if (f) { octstr_destroy(f); diff --git a/mbuni/mmlib/mms_msg.c b/mbuni/mmlib/mms_msg.c index 45853e5..3247437 100644 --- a/mbuni/mmlib/mms_msg.c +++ b/mbuni/mmlib/mms_msg.c @@ -264,14 +264,17 @@ static Octstr *decode_encoded_string_value(int ret, ParseContext *context, unsig if (ret2 == WSP_FIELD_VALUE_DATA) { /* expect charset text. */ long charset; /* Get it and ignore it. */ + Octstr *xs; wsp_secondary_field_value(context, &charset); - res = parse_get_nul_string(context); /* XXX Currently we ignore charset */ + xs = parse_get_nul_string(context); if (ret < 0) { parse_skip_to_limit(context); parse_pop_limit(context); } + res = pack_rfc2047_text(xs, charset); + octstr_destroy(xs); } else if (ret2 != WSP_FIELD_VALUE_NUL_STRING) { mms_warning(0, "mms_msg", NULL, "Faulty header value for %s! [ret=%d,ret2=%d]\n", hname,ret,ret2); res = octstr_imm(""); @@ -694,8 +697,19 @@ static void mms_pack_well_known_field(Octstr *os, int field_type, Octstr *value) case MMS_HEADER_RETRIEVE_TEXT: case MMS_HEADER_STORE_STATUS_TEXT: - - wsp_pack_text(os, value); /* XXX need to deal with charset issues. */ + { + int charset; + Octstr *xvalue = parse_rfc2047_text(value, &charset); + + if (charset == US_ASCII_MIB_VAL) + wsp_pack_text(os, xvalue); + else { /* Need to use the other encoding */ + wsp_pack_integer_value(encoded, charset); + wsp_pack_text(encoded,xvalue); + wsp_pack_value(os, encoded); + } + octstr_destroy(xvalue); + } break; case MMS_HEADER_RESPONSE_TEXT: /* make sure response status does not begin with digit!! Has special meaning*/ diff --git a/mbuni/mmlib/mms_queue.c b/mbuni/mmlib/mms_queue.c index 86171ab..4585ce3 100644 --- a/mbuni/mmlib/mms_queue.c +++ b/mbuni/mmlib/mms_queue.c @@ -383,9 +383,17 @@ static MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int sho /* We should properly validate the queue file here. */ if (!okfile) { + struct stat st; + int rx; + + if ((rx = stat(xqf, &st)) < 0 || + st.st_size == 0) { /* Attempt removal */ + unlink(xqf); + mms_error(0, "mms_queue", NULL, "Corrupt queue control file [%s], removed!", xqf); + } else + mms_error(0, "mms_queue", NULL, "Corrupt queue control file: %s", xqf); free_envelope(e,0); - e = NULL; - mms_error(0, "mms_queue", NULL, "Corrupt queue control file: %s", xqf); + e = NULL; } return e; } diff --git a/mbuni/mmlib/mms_util.c b/mbuni/mmlib/mms_util.c index 0ed1c74..793f3a1 100644 --- a/mbuni/mmlib/mms_util.c +++ b/mbuni/mmlib/mms_util.c @@ -1365,13 +1365,13 @@ unsigned long _mshash(char *s) return h; } -int isphonenum(Octstr *s) +int isphonenum_ex(Octstr *s, int offset) { - int i = 0, n = octstr_len(s); + int i = offset, n = octstr_len(s); char *cs; if (s && octstr_len(s) >= 1 && - octstr_get_cstr(s)[0] == '+') + octstr_get_char(s, i) == '+') i++; for ( cs = octstr_get_cstr(s); i= 0) { + Octstr *charset = octstr_copy(xs, 0, n); + + octstr_delete(xs, 0, 1+octstr_len(charset)); + *mibenum = charset_to_mibenum(octstr_get_cstr(charset)); + octstr_destroy(charset); + + offset += n+1; + } else + *mibenum = US_ASCII_MIB_VAL; + + /* Get encoding */ + if ((n = octstr_search_char(xs, '?', 0)) >= 0) { + enc = octstr_get_char(xs, n-1); + octstr_delete(xs, 0, 2); /* Delete the encoding, and the following '?' */ + offset += n+2; + } else + enc = 'q'; + + + /* Look for end marker */ + if ((n = octstr_search(xs, octstr_imm("?="), 0)) >= 0) { + octstr_delete(xs, n, octstr_len(xs)); /* Remove everything after that */ + offset += n+2; + } else + offset += octstr_len(xs); + + if (toupper(enc) == 'B') + octstr_base64_to_binary(xs); + else /* Assume plain text, deal with =20 and _ issues */ + for (i = 0; i < octstr_len(xs); i++) + if (octstr_get_char(xs, i) == '=' && + (ch = octstr_get_char(xs,i+1)) > 0 && + (ch2 = octstr_get_char(xs,i+2)) > 0 && + isxdigit(ch) && isxdigit(ch2)) { + sscanf(octstr_get_cstr(xs) + i + 1, "%2x", &ch); + + octstr_delete(xs, i, 3); + octstr_insert_char(xs, i,ch); + } else if (octstr_get_char(xs, i) == '_') { + octstr_delete(xs, i, 1); + octstr_insert_char(xs, i,0x20); + } + + *end_marker = offset; + return xs; +} + +/* Output charset will be forced to UTF8 if multiple atoms exist */ +Octstr *parse_rfc2047_text(Octstr *in, int *mibenum) +{ + int n1, mib, end, last_mib = -1, offset = 0; + Octstr *x = NULL, *xs = NULL; + + *mibenum = US_ASCII_MIB_VAL; /* Default */ + if (in == NULL) + goto done; + x = octstr_create(""); + while ((n1 = octstr_search(in, octstr_imm("=?"), offset)) >= 0 && + (xs = parse_rfc2047_atom(in, n1, &mib, &end)) != NULL) { + Octstr *x1 = octstr_copy(in, offset, n1 - offset); /* Copy all the stuff up to this point. */ + + octstr_append(x, x1); + + if (last_mib >= 0 && mib != last_mib) { + /* Force all to be utf-8 encoded */ + const char *charset1 = mibenum_to_charset(mib); + Octstr *xcharset1 = octstr_imm(charset1); + + const char *charset2 = mibenum_to_charset(last_mib); + Octstr *xcharset2 = octstr_imm(charset2); + Octstr *xout = NULL; + + /* Convert old stuff to utf8 */ + if (last_mib != UTF8_MIB_VAL) { + if (charset_to_utf8(x, &xout, xcharset2) > 0 && xout) { + octstr_destroy(x); + x = xout; + } else + octstr_destroy(xout); + xout = NULL; + } + + /* Convert new string and append it */ + if (mib != UTF8_MIB_VAL) { + if (charset_to_utf8(xs, &xout, xcharset1) > 0 && xout) { + octstr_destroy(xs); + xs = xout; + } else + octstr_destroy(xout); + xout = NULL; + } + + mib = UTF8_MIB_VAL; /* Force all subsequent to utf8 */ + } + + octstr_append(x, xs); /* Put it in */ + + last_mib = *mibenum = mib; + + offset = end; + + octstr_destroy(x1); + octstr_destroy(xs); + xs = NULL; + } + + octstr_destroy(xs); /* Because it might have escaped */ + if (offset < octstr_len(in)) { + Octstr *x1 = octstr_copy(in, offset, octstr_len(in)); /* Copy all the stuff up to this point. Ignore charset*/ + octstr_append(x, x1); + octstr_destroy(x1); + } + +done: + return x; +} + +Octstr *pack_rfc2047_text(Octstr *in, int charset_mib_enum) +{ + int i; + Octstr *xs; + if (charset_mib_enum == US_ASCII_MIB_VAL) + return octstr_duplicate(in); + + xs = octstr_format("=?%s?q?", mibenum_to_charset(charset_mib_enum)); + + for (i = 0; i 127) + octstr_format_append(xs,"=%02X", ch); + else + octstr_append_char(xs, ch); + } + octstr_append_cstr(xs, "?="); + return xs; +} diff --git a/mbuni/mmlib/mms_util.h b/mbuni/mmlib/mms_util.h index cc22c8b..99b4cc3 100644 --- a/mbuni/mmlib/mms_util.h +++ b/mbuni/mmlib/mms_util.h @@ -173,6 +173,8 @@ unsigned long _mshash(char *s); /* Tell us whether address is a phone number. */ int isphonenum(Octstr *s); +int isphonenum_ex(Octstr *s, int offset); + /* Fixup an address: Normalize number (if prefix given), Add type (if keep_suffix is set), etc. */ void _mms_fixup_address(Octstr **address, char *unified_prefix, List *strip_prefixes, int keep_suffix); @@ -249,6 +251,16 @@ void *_mms_load_module(mCfg *cfg, mCfgGrp *grp, char *config_key, char *symbolna void fixup_address_type(List *headers, char *hdr, char *unified_prefix, List *strip_prefixes); + +/* Convert charset mib enum to charset and vice versa */ +extern const char *mibenum_to_charset(int val); +extern int charset_to_mibenum(char *charset); +Octstr *pack_rfc2047_text(Octstr *in, int charset_mib_enum); +Octstr *parse_rfc2047_text(Octstr *in, int *mibenum); + +#define US_ASCII_MIB_VAL 3 +#define UTF8_MIB_VAL 106 + #define MAXQTRIES 100 #define BACKOFF_FACTOR 5*60 /* In seconds */ #define QUEUERUN_INTERVAL 1*60 /* 1 minutes. */