diff --git a/Cargo.lock b/Cargo.lock index 163a27e0c..152e9dcb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,7 +52,7 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.23" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -84,7 +84,7 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -93,13 +93,13 @@ version = "0.1.1" source = "git+https://github.com/async-email/async-imap#377d40837028b454c6365ff13e3f35cc341a908e" dependencies = [ "async-attributes 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "async-std 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "async-tls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures_codec 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures_codec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "imap-proto 0.9.1 (git+https://github.com/djc/tokio-imap)", "nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -118,7 +118,7 @@ dependencies = [ [[package]] name = "async-std" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "async-macros 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -133,7 +133,7 @@ dependencies = [ "kv-log-macro 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.20 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -166,7 +166,7 @@ name = "atty" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -181,8 +181,8 @@ version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -192,7 +192,7 @@ version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -360,9 +360,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -391,7 +391,7 @@ dependencies = [ [[package]] name = "cfg-if" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -405,10 +405,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -459,8 +458,8 @@ dependencies = [ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "publicsuffix 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -476,7 +475,7 @@ name = "crc32fast" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -502,7 +501,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -522,7 +521,7 @@ name = "crossbeam-utils" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -532,7 +531,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -550,7 +549,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -562,7 +561,7 @@ dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -611,14 +610,14 @@ name = "deltachat" version = "1.0.0-beta.8" dependencies = [ "async-imap 0.1.1 (git+https://github.com/async-email/async-imap)", - "async-std 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "async-tls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "charset 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "debug_stub_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "deltachat_derive 0.1.0", "escaper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -627,11 +626,11 @@ dependencies = [ "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "image-meta 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jetscii 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lettre 0.9.2 (git+https://github.com/deltachat/lettre?branch=feat/rustls)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "mmime 0.1.2", + "lettre 0.9.2 (git+https://github.com/deltachat/lettre?branch=feat/mail)", + "lettre_email 0.9.2 (git+https://github.com/deltachat/lettre?branch=feat/mail)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "mailparse 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -640,7 +639,7 @@ dependencies = [ "pretty_env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)", "quick-xml 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "r2d2 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2_sqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -649,8 +648,8 @@ dependencies = [ "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustyline 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "sanitize-filename 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "stop-token 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -687,8 +686,9 @@ version = "1.0.0-beta.8" dependencies = [ "deltachat 1.0.0-beta.8", "deltachat-provider-database 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "human-panic 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -754,7 +754,7 @@ name = "dirs" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -782,12 +782,83 @@ name = "either" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "email" +version = "0.0.21" +source = "git+https://github.com/deltachat/rust-email#265a54a8c31355c506610c032c81112dc0953afb" +dependencies = [ + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "encoding" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "encoding-index-japanese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "encoding-index-korean" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "encoding-index-simpchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "encoding-index-singlebyte" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "encoding-index-tradchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "encoding_index_tests" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "encoding_rs" version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -840,7 +911,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -872,9 +943,9 @@ name = "flate2" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -981,7 +1052,7 @@ dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1035,12 +1106,13 @@ dependencies = [ [[package]] name = "futures_codec" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1056,8 +1128,8 @@ name = "getrandom" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1080,7 +1152,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1101,7 +1173,7 @@ name = "hermit-abi" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1114,13 +1186,13 @@ name = "hostname" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "http" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1135,7 +1207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1152,8 +1224,8 @@ dependencies = [ "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "os_type 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1177,7 +1249,7 @@ dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1188,12 +1260,12 @@ dependencies = [ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1269,7 +1341,7 @@ name = "iovec" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1285,11 +1357,6 @@ name = "itoa" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "jetscii" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "js-sys" version = "0.3.32" @@ -1331,9 +1398,9 @@ dependencies = [ [[package]] name = "lettre" version = "0.9.2" -source = "git+https://github.com/deltachat/lettre?branch=feat/rustls#a422872e92e8cf089bdfb24489f3446f9865ba19" +source = "git+https://github.com/deltachat/lettre?branch=feat/mail#00ba9db544059ddd60048f0b85d5052e4bf605da" dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "fast_chemail 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", "hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1341,19 +1408,32 @@ dependencies = [ "nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustls-connector 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lettre_email" +version = "0.9.2" +source = "git+https://github.com/deltachat/lettre?branch=feat/mail#00ba9db544059ddd60048f0b85d5052e4bf605da" +dependencies = [ + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "email 0.0.21 (git+https://github.com/deltachat/rust-email)", + "lettre 0.9.2 (git+https://github.com/deltachat/lettre?branch=feat/mail)", + "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "lexical-core" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1361,7 +1441,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.65" +version = "0.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1386,7 +1466,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lock_api" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1397,7 +1477,7 @@ name = "log" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1413,7 +1493,17 @@ name = "mach" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mailparse" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "charset 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quoted_printable 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1441,15 +1531,6 @@ name = "memchr" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "memmap" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "memoffset" version = "0.5.3" @@ -1482,15 +1563,15 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1504,8 +1585,8 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1519,26 +1600,13 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "mmime" -version = "0.1.2" -dependencies = [ - "charset 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1549,8 +1617,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1591,7 +1659,7 @@ dependencies = [ "num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1639,7 +1707,7 @@ version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1673,7 +1741,7 @@ name = "packed_simd" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1681,25 +1749,47 @@ name = "parking_lot" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot_core" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot_core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "percent-encoding" version = "1.0.1" @@ -1725,7 +1815,7 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "cast5 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfb-mode 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "circular 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "crc24 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1757,6 +1847,24 @@ dependencies = [ "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pin-project" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pin-project-lite" version = "0.1.1" @@ -1793,7 +1901,7 @@ name = "pretty_env_logger" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1805,7 +1913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1906,14 +2014,19 @@ dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quoted_printable" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "r2d2" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "scheduled-thread-pool 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scheduled-thread-pool 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1921,7 +2034,7 @@ name = "r2d2_sqlite" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "r2d2 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", "rusqlite 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1931,7 +2044,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1943,7 +2056,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "packed_simd 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1962,7 +2075,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2036,7 +2149,7 @@ name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2048,7 +2161,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2135,7 +2248,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2150,23 +2263,23 @@ dependencies = [ "encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-rustls 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-rustls 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2180,7 +2293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2210,7 +2323,7 @@ dependencies = [ "num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2290,7 +2403,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2329,10 +2442,10 @@ dependencies = [ [[package]] name = "scheduled-thread-pool" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2355,7 +2468,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2365,30 +2478,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2398,7 +2511,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2446,7 +2559,7 @@ dependencies = [ "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2461,7 +2574,7 @@ name = "slice-deque" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2504,7 +2617,7 @@ name = "stop-token" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-std 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2542,12 +2655,12 @@ dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "subtle" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2582,7 +2695,7 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.8" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2605,7 +2718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2623,8 +2736,8 @@ name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2668,7 +2781,7 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2680,15 +2793,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.20 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2707,12 +2820,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-executor" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2731,18 +2844,18 @@ dependencies = [ [[package]] name = "tokio-reactor" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.20 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2777,9 +2890,9 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.20 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2795,18 +2908,18 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-timer" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2814,7 +2927,7 @@ name = "toml" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2832,7 +2945,7 @@ name = "try_from" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2942,7 +3055,7 @@ name = "uuid" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2979,7 +3092,7 @@ name = "wait-timeout" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3012,7 +3125,7 @@ name = "wasm-bindgen" version = "0.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-macro 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3026,7 +3139,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3046,7 +3159,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3061,12 +3174,12 @@ name = "wasm-bindgen-webidl" version = "0.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3076,7 +3189,7 @@ name = "web-sys" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3228,7 +3341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3239,7 +3352,7 @@ dependencies = [ "checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum anyhow 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1072d8f55592084072d2d3cb23a4b680a8543c00f10d446118e85ad3718142" +"checksum anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" @@ -3247,7 +3360,7 @@ dependencies = [ "checksum async-attributes 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423" "checksum async-imap 0.1.1 (git+https://github.com/async-email/async-imap)" = "" "checksum async-macros 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "644a5a8de80f2085a1e7e57cd1544a2a7438f6e003c0790999bd43b92a77cdb2" -"checksum async-std 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56933da6903b273923d13f4746d829f66ff9b444173f6743d831e80f4da15446" +"checksum async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "513ee3c49800679a319912340f5601afda9e72848d7dea3a48bab489e8c1a46f" "checksum async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de6bd58f7b9cc49032559422595c81cbfcf04db2f2133592f70af19e258a1ced" "checksum async-tls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce6977f57fa68da77ffe5542950d47e9c23d65f5bc7cb0a9f8700996913eec7" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" @@ -3279,9 +3392,9 @@ dependencies = [ "checksum cast5 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ce5759b4c52ca74f9a98421817c882f1fd9b0071ae41cd61ab9f9d059c04fd6" "checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" "checksum cfb-mode 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "190e7b55d3a27cf8879becf61035a141cbc783f3258a41d16d1706719f991345" -"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum charset 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4f426e64df1c3de26cbf44593c6ffff5dbfd43bbf9de0d075058558126b3fc73" -"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" +"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" "checksum circular 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0fc239e0f6cb375d2402d48afb92f76f5404fd1df208a41930ec81eda078bea" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" @@ -3314,6 +3427,14 @@ dependencies = [ "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum ed25519-dalek 1.0.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)" = "845aaacc16f01178f33349e7c992ecd0cee095aa5e577f0f4dee35971bd36455" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +"checksum email 0.0.21 (git+https://github.com/deltachat/rust-email)" = "" +"checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" +"checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" +"checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" +"checksum encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" +"checksum encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" +"checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" +"checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9" "checksum entities 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" @@ -3346,7 +3467,7 @@ dependencies = [ "checksum futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" "checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" "checksum futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d" -"checksum futures_codec 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8efb8edac092482013e203af800eef158349c8bbf461edff59c5dd2d3c00e87" +"checksum futures_codec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "793d2283ff61ffff52d51cc631be0c8e75370d96056a38e09f124a67263913da" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" @@ -3356,7 +3477,7 @@ dependencies = [ "checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" "checksum hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" "checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e" -"checksum http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d7e06e336150b178206af098a055e3621e8336027e2b4d126bda0bc64824baaf" +"checksum http 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "2790658cddc82e82b08e25176c431d7015a0adeb1718498715cbd20138a0bf68" "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum human-panic 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21638c5955a6daf3ecc42cae702335fc37a72a4abcc6959ce457b31a7d43bbdd" @@ -3372,32 +3493,32 @@ dependencies = [ "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum jetscii 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5f25cca2463cb19dbb1061eb3bd38a8b5e4ce1cc5a5a9fc0e02de486d92b9b05" "checksum js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "1c840fdb2167497b0bd0db43d6dfe61e91637fa72f9d061f8bd17ddc44ba6414" "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kv-log-macro 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c54d9f465d530a752e6ebdc217e081a7a614b48cb200f6f0aee21ba6bc9aabb" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum lettre 0.9.2 (git+https://github.com/deltachat/lettre?branch=feat/rustls)" = "" +"checksum lettre 0.9.2 (git+https://github.com/deltachat/lettre?branch=feat/mail)" = "" +"checksum lettre_email 0.9.2 (git+https://github.com/deltachat/lettre?branch=feat/mail)" = "" "checksum lexical-core 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2304bccb228c4b020f3a4835d247df0a02a7c4686098d4167762cfbbe4c5cb14" -"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" +"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" "checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" "checksum libsqlite3-sys 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5b95e89c330291768dc840238db7f9e204fd208511ab6319b56193a7f2ae25" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" -"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" +"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" +"checksum mailparse 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c00eb97cc18f08aaadd02808328dcc9be94948d8e5b54adbfd3414d2f87f7bf1" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" -"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" "checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf" "checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599" "checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" -"checksum mio 0.6.20 (registry+https://github.com/rust-lang/crates.io-index)" = "72f4261ee7ab03cd36dc99eea4db8be6e83e4164da470e0c84f6726d6c605855" +"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" @@ -3416,11 +3537,15 @@ dependencies = [ "checksum os_type 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7edc011af0ae98b7f88cf7e4a83b70a54a75d2b8cb013d6efd02e5956207e9eb" "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" "checksum packed_simd 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220" +"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" "checksum pgp 0.3.2 (git+https://github.com/rpgp/rpgp)" = "" +"checksum pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "94b90146c7216e4cb534069fb91366de4ea0ea353105ee45ed297e2d1619e469" +"checksum pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "44ca92f893f0656d3cba8158dd0f2b99b94de256a4a54e870bd6922fcc6c8355" "checksum pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f0af6cbca0e6e3ce8692ee19fb8d734b641899e07b68eb73e9bbbd32f1703991" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" @@ -3439,7 +3564,8 @@ dependencies = [ "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -"checksum r2d2 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e48fa64898ef0286b6ee4b4d8f61483f9182acf5e44e62a398b1c7f56f2f861d" +"checksum quoted_printable 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "86cedf331228892e747bb85beb130b6bb23fc628c40dde9ea01eb6becea3c798" +"checksum r2d2 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "22b5c5fc5fba064373f03887337b412e0e1562d63023393db77251146cb75553" "checksum r2d2_sqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "806e268035ce9e5a604bf617ac8a073ef28b59ef2e48e8338db0baf530caef33" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" @@ -3480,14 +3606,14 @@ dependencies = [ "checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" "checksum sanitize-filename 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23fd0fec94ec480abfd86bb8f4f6c57e0efb36dac5c852add176ea7b04c74801" -"checksum scheduled-thread-pool 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd07742e081ff6c077f5f6b283f12f32b9e7cc765b316160d66289b74546fbb3" +"checksum scheduled-thread-pool 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f5de7bc31f28f8e6c28df5e1bf3d10610f5fdc14cc95f272853512c70a2bd779" "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" -"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8" -"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" +"checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702" +"checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0" +"checksum serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)" = "1a3351dcbc1f067e2c92ab7c3c1f288ad1a4cffc470b5aaddb4c2e0a3ae80043" "checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" "checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" @@ -3507,11 +3633,11 @@ dependencies = [ "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum strum 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6138f8f88a16d90134763314e3fc76fa3ed6a7db4725d6acf9a3ef95a3188d22" "checksum strum_macros 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81" -"checksum subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab3af2eb31c42e8f0ccf43548232556c42737e01a96db6e1777b0be108e79799" +"checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -"checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" +"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" @@ -3524,14 +3650,14 @@ dependencies = [ "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" "checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" "checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" -"checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" +"checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c56391be9805bc80163151c0b9e5164ee64f4b0200962c346fea12773158f22d" +"checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" "checksum tokio-rustls 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1df2fa53ac211c136832f530ccb081af9af891af22d685a9493e232c7a359bc2" "checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" "checksum tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd2c6a3885302581f4401c82af70d792bb9df1700e7437b0aeb4ada94d5388c" -"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" +"checksum tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" diff --git a/Cargo.toml b/Cargo.toml index 4ba349169..9e12520ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,6 @@ license = "MPL" [dependencies] deltachat_derive = { path = "./deltachat_derive" } -mmime = { version = "0.1.2", path = "./mmime" } libc = "0.2.51" pgp = { git = "https://github.com/rpgp/rpgp", branch = "master", default-features = false } @@ -18,11 +17,12 @@ smallvec = "0.6.9" reqwest = { version = "0.9.15", default-features = false, features = ["rustls-tls"] } num-derive = "0.2.5" num-traits = "0.2.6" -lettre = { git = "https://github.com/deltachat/lettre", branch = "feat/rustls" } +lettre = { git = "https://github.com/deltachat/lettre", branch = "feat/mail" } +lettre_email = { git = "https://github.com/deltachat/lettre", branch = "feat/mail" } async-imap = { git = "https://github.com/async-email/async-imap", branch="master" } async-tls = "0.6" async-std = { version = "1.0", features = ["unstable"] } -base64 = "0.10" +base64 = "0.11" charset = "0.1" percent-encoding = "2.0" serde = { version = "1.0", features = ["derive"] } @@ -47,13 +47,13 @@ image-meta = "0.1.0" quick-xml = "0.15.0" escaper = "0.1.0" bitflags = "1.1.0" -jetscii = "0.4.4" debug_stub_derive = "0.3.0" sanitize-filename = "0.2.1" stop-token = { version = "0.1.1", features = ["unstable"] } rustls = "0.16.0" webpki-roots = "0.18.0" webpki = "0.21.0" +mailparse = "0.10.1" [dev-dependencies] tempfile = "3.0" @@ -65,7 +65,6 @@ proptest = "0.9.4" members = [ "deltachat-ffi", "deltachat_derive", - "mmime", ] [[example]] diff --git a/deltachat-ffi/Cargo.toml b/deltachat-ffi/Cargo.toml index 39f293366..c154d924a 100644 --- a/deltachat-ffi/Cargo.toml +++ b/deltachat-ffi/Cargo.toml @@ -20,6 +20,7 @@ deltachat-provider-database = "0.2.1" libc = "0.2" human-panic = "1.0.1" num-traits = "0.2.6" +failure = "0.1.6" [features] default = ["vendored", "nightly", "ringbuf"] diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 1a25a84a5..dbd21e068 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -25,13 +25,13 @@ use num_traits::{FromPrimitive, ToPrimitive}; use deltachat::constants::DC_MSG_ID_LAST_SPECIAL; use deltachat::contact::Contact; use deltachat::context::Context; -use deltachat::dc_tools::{ - as_path, dc_strdup, to_opt_string_lossy, to_string_lossy, OsStrExt, StrExt, -}; use deltachat::message::MsgId; use deltachat::stock::StockMessage; use deltachat::*; +mod string; +use self::string::*; + // as C lacks a good and portable error handling, // in general, the C Interface is forgiving wrt to bad parameters. // - objects returned by some functions diff --git a/deltachat-ffi/src/providers.rs b/deltachat-ffi/src/providers.rs index ceaa0d5ae..42c169c77 100644 --- a/deltachat-ffi/src/providers.rs +++ b/deltachat-ffi/src/providers.rs @@ -2,7 +2,7 @@ extern crate deltachat_provider_database; use std::ptr; -use deltachat::dc_tools::{to_string_lossy, StrExt}; +use crate::string::{to_string_lossy, StrExt}; use deltachat_provider_database::StatusState; #[no_mangle] diff --git a/deltachat-ffi/src/string.rs b/deltachat-ffi/src/string.rs new file mode 100644 index 000000000..8baf4d56a --- /dev/null +++ b/deltachat-ffi/src/string.rs @@ -0,0 +1,350 @@ +use failure::Fail; +use std::ffi::{CStr, CString}; + +/// Duplicates a string +/// +/// returns an empty string if NULL is given, never returns NULL (exits on errors) +/// +/// # Examples +/// +/// ```rust,norun +/// use deltachat::dc_tools::{dc_strdup, to_string_lossy}; +/// unsafe { +/// let str_a = b"foobar\x00" as *const u8 as *const libc::c_char; +/// let str_a_copy = dc_strdup(str_a); +/// assert_eq!(to_string_lossy(str_a_copy), "foobar"); +/// assert_ne!(str_a, str_a_copy); +/// } +/// ``` +pub unsafe fn dc_strdup(s: *const libc::c_char) -> *mut libc::c_char { + let ret: *mut libc::c_char; + if !s.is_null() { + ret = libc::strdup(s); + assert!(!ret.is_null()); + } else { + ret = libc::calloc(1, 1) as *mut libc::c_char; + assert!(!ret.is_null()); + } + + ret +} + +/// Error type for the [OsStrExt] trait +#[derive(Debug, Fail, PartialEq)] +pub enum CStringError { + /// The string contains an interior null byte + #[fail(display = "String contains an interior null byte")] + InteriorNullByte, + /// The string is not valid Unicode + #[fail(display = "String is not valid unicode")] + NotUnicode, +} + +/// Extra convenience methods on [std::ffi::OsStr] to work with `*libc::c_char`. +/// +/// The primary function of this trait is to more easily convert +/// [OsStr], [OsString] or [Path] into pointers to C strings. This always +/// allocates a new string since it is very common for the source +/// string not to have the required terminal null byte. +/// +/// It is implemented for `AsRef>` trait, which +/// allows any type which implements this trait to transparently use +/// this. This is how the conversion for [Path] works. +/// +/// [OsStr]: std::ffi::OsStr +/// [OsString]: std::ffi::OsString +/// [Path]: std::path::Path +/// +/// # Example +/// +/// ``` +/// use deltachat::dc_tools::{dc_strdup, OsStrExt}; +/// let path = std::path::Path::new("/some/path"); +/// let path_c = path.to_c_string().unwrap(); +/// unsafe { +/// let mut c_ptr: *mut libc::c_char = dc_strdup(path_c.as_ptr()); +/// } +/// ``` +pub trait OsStrExt { + /// Convert a [std::ffi::OsStr] to an [std::ffi::CString] + /// + /// This is useful to convert e.g. a [std::path::Path] to + /// [*libc::c_char] by using + /// [Path::as_os_str()](std::path::Path::as_os_str) and + /// [CStr::as_ptr()](std::ffi::CStr::as_ptr). + /// + /// This returns [CString] and not [&CStr] because not all [OsStr] + /// slices end with a null byte, particularly those coming from + /// [Path] do not have a null byte and having to handle this as + /// the caller would defeat the point of this function. + /// + /// On Windows this requires that the [OsStr] contains valid + /// unicode, which should normally be the case for a [Path]. + /// + /// [CString]: std::ffi::CString + /// [CStr]: std::ffi::CStr + /// [OsStr]: std::ffi::OsStr + /// [Path]: std::path::Path + /// + /// # Errors + /// + /// Since a C `*char` is terminated by a NULL byte this conversion + /// will fail, when the [OsStr] has an interior null byte. The + /// function will return + /// `[Err]([CStringError::InteriorNullByte])`. When converting + /// from a [Path] it should be safe to + /// [`.unwrap()`](std::result::Result::unwrap) this anyway since a + /// [Path] should not contain interior null bytes. + /// + /// On windows when the string contains invalid Unicode + /// `[Err]([CStringError::NotUnicode])` is returned. + fn to_c_string(&self) -> Result; +} + +impl> OsStrExt for T { + #[cfg(not(target_os = "windows"))] + fn to_c_string(&self) -> Result { + use std::os::unix::ffi::OsStrExt; + CString::new(self.as_ref().as_bytes()).map_err(|err| match err { + std::ffi::NulError { .. } => CStringError::InteriorNullByte, + }) + } + + #[cfg(target_os = "windows")] + fn to_c_string(&self) -> Result { + os_str_to_c_string_unicode(&self) + } +} + +// Implementation for os_str_to_c_string on windows. +#[allow(dead_code)] +fn os_str_to_c_string_unicode( + os_str: &dyn AsRef, +) -> Result { + match os_str.as_ref().to_str() { + Some(val) => CString::new(val.as_bytes()).map_err(|err| match err { + std::ffi::NulError { .. } => CStringError::InteriorNullByte, + }), + None => Err(CStringError::NotUnicode), + } +} + +/// Convenience methods/associated functions for working with [CString] +/// +/// This is helps transitioning from unsafe code. +pub trait CStringExt { + /// Create a new [CString], yolo style + /// + /// This unwrap the result, panicking when there are embedded NULL + /// bytes. + fn yolo>>(t: T) -> CString { + CString::new(t).expect("String contains null byte, can not be CString") + } +} + +impl CStringExt for CString {} + +/// Convenience methods to make transitioning from raw C strings easier. +/// +/// To interact with (legacy) C APIs we often need to convert from +/// Rust strings to raw C strings. This can be clumsy to do correctly +/// and the compiler sometimes allows it in an unsafe way. These +/// methods make it more succinct and help you get it right. +pub trait StrExt { + /// Allocate a new raw C `*char` version of this string. + /// + /// This allocates a new raw C string which must be freed using + /// `free`. It takes care of some common pitfalls with using + /// [CString.as_ptr]. + /// + /// [CString.as_ptr]: std::ffi::CString.as_ptr + /// + /// # Panics + /// + /// This function will panic when the original string contains an + /// interior null byte as this can not be represented in raw C + /// strings. + unsafe fn strdup(&self) -> *mut libc::c_char; +} + +impl> StrExt for T { + unsafe fn strdup(&self) -> *mut libc::c_char { + let tmp = CString::yolo(self.as_ref()); + dc_strdup(tmp.as_ptr()) + } +} + +pub fn to_string_lossy(s: *const libc::c_char) -> String { + if s.is_null() { + return "".into(); + } + + let cstr = unsafe { CStr::from_ptr(s) }; + + cstr.to_string_lossy().to_string() +} + +pub fn to_opt_string_lossy(s: *const libc::c_char) -> Option { + if s.is_null() { + return None; + } + + Some(to_string_lossy(s)) +} + +/// Convert a C `*char` pointer to a [std::path::Path] slice. +/// +/// This converts a `*libc::c_char` pointer to a [Path] slice. This +/// essentially has to convert the pointer to [std::ffi::OsStr] to do +/// so and thus is the inverse of [OsStrExt::to_c_string]. Just like +/// [OsStrExt::to_c_string] requires valid Unicode on Windows, this +/// requires that the pointer contains valid UTF-8 on Windows. +/// +/// Because this returns a reference the [Path] silce can not outlive +/// the original pointer. +/// +/// [Path]: std::path::Path +#[cfg(not(target_os = "windows"))] +pub fn as_path<'a>(s: *const libc::c_char) -> &'a std::path::Path { + assert!(!s.is_null(), "cannot be used on null pointers"); + use std::os::unix::ffi::OsStrExt; + unsafe { + let c_str = std::ffi::CStr::from_ptr(s).to_bytes(); + let os_str = std::ffi::OsStr::from_bytes(c_str); + std::path::Path::new(os_str) + } +} + +// as_path() implementation for windows, documented above. +#[cfg(target_os = "windows")] +pub fn as_path<'a>(s: *const libc::c_char) -> &'a std::path::Path { + as_path_unicode(s) +} + +// Implementation for as_path() on Windows. +// +// Having this as a separate function means it can be tested on unix +// too. +#[allow(dead_code)] +fn as_path_unicode<'a>(s: *const libc::c_char) -> &'a std::path::Path { + assert!(!s.is_null(), "cannot be used on null pointers"); + + let cstr = unsafe { CStr::from_ptr(s) }; + let str = cstr.to_str().unwrap_or_else(|err| panic!("{}", err)); + + std::path::Path::new(str) +} + +#[cfg(test)] +mod tests { + use super::*; + use libc::{free, strcmp}; + + #[test] + fn test_os_str_to_c_string_cwd() { + let some_dir = std::env::current_dir().unwrap(); + some_dir.as_os_str().to_c_string().unwrap(); + } + + #[test] + fn test_os_str_to_c_string_unicode() { + let some_str = String::from("/some/valid/utf8"); + let some_dir = std::path::Path::new(&some_str); + assert_eq!( + some_dir.as_os_str().to_c_string().unwrap(), + CString::new("/some/valid/utf8").unwrap() + ); + } + + #[test] + fn test_os_str_to_c_string_nul() { + let some_str = std::ffi::OsString::from("foo\x00bar"); + assert_eq!( + some_str.to_c_string().err().unwrap(), + CStringError::InteriorNullByte + ) + } + + #[test] + fn test_path_to_c_string_cwd() { + let some_dir = std::env::current_dir().unwrap(); + some_dir.to_c_string().unwrap(); + } + + #[test] + fn test_path_to_c_string_unicode() { + let some_str = String::from("/some/valid/utf8"); + let some_dir = std::path::Path::new(&some_str); + assert_eq!( + some_dir.as_os_str().to_c_string().unwrap(), + CString::new("/some/valid/utf8").unwrap() + ); + } + + #[test] + fn test_os_str_to_c_string_unicode_fn() { + let some_str = std::ffi::OsString::from("foo"); + assert_eq!( + os_str_to_c_string_unicode(&some_str).unwrap(), + CString::new("foo").unwrap() + ); + } + + #[test] + fn test_path_to_c_string_unicode_fn() { + let some_str = String::from("/some/path"); + let some_path = std::path::Path::new(&some_str); + assert_eq!( + os_str_to_c_string_unicode(&some_path).unwrap(), + CString::new("/some/path").unwrap() + ); + } + + #[test] + fn test_os_str_to_c_string_unicode_fn_nul() { + let some_str = std::ffi::OsString::from("fooz\x00bar"); + assert_eq!( + os_str_to_c_string_unicode(&some_str).err().unwrap(), + CStringError::InteriorNullByte + ); + } + + #[test] + fn test_as_path() { + let some_path = CString::new("/some/path").unwrap(); + let ptr = some_path.as_ptr(); + assert_eq!(as_path(ptr), std::ffi::OsString::from("/some/path")) + } + + #[test] + fn test_as_path_unicode_fn() { + let some_path = CString::new("/some/path").unwrap(); + let ptr = some_path.as_ptr(); + assert_eq!(as_path_unicode(ptr), std::ffi::OsString::from("/some/path")); + } + + #[test] + fn test_cstring_yolo() { + assert_eq!(CString::new("hello").unwrap(), CString::yolo("hello")); + } + + #[test] + fn test_strdup_str() { + unsafe { + let s = "hello".strdup(); + let cmp = strcmp(s, b"hello\x00" as *const u8 as *const libc::c_char); + free(s as *mut libc::c_void); + assert_eq!(cmp, 0); + } + } + + #[test] + fn test_strdup_string() { + unsafe { + let s = String::from("hello").strdup(); + let cmp = strcmp(s, b"hello\x00" as *const u8 as *const libc::c_char); + free(s as *mut libc::c_void); + assert_eq!(cmp, 0); + } + } +} diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index d7776d557..2e465aca1 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -19,12 +19,11 @@ use deltachat::peerstate::*; use deltachat::qr::*; use deltachat::sql; use deltachat::Event; -use libc::free; /// Reset database tables. This function is called from Core cmdline. /// Argument is a bitmask, executing single or multiple actions in one call. /// e.g. bitmask 7 triggers actions definded with bits 1, 2 and 4. -pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 { +pub fn dc_reset_tables(context: &Context, bits: i32) -> i32 { info!(context, "Resetting tables ({})...", bits); if 0 != bits & 1 { sql::execute(context, &context.sql, "DELETE FROM jobs;", params![]).unwrap(); @@ -95,7 +94,7 @@ pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 { fn dc_poke_eml_file(context: &Context, filename: impl AsRef) -> Result<(), Error> { let data = dc_read_file(context, filename)?; - unsafe { dc_receive_imf(context, &data, "import", 0, 0) }; + dc_receive_imf(context, &data, "import", 0, 0); Ok(()) } @@ -107,18 +106,19 @@ fn dc_poke_eml_file(context: &Context, filename: impl AsRef) -> Result<(), /// @param context The context as created by dc_context_new(). /// @param spec The file or directory to import. NULL for the last command. /// @return 1=success, 0=error. -fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int { +fn poke_spec(context: &Context, spec: Option<&str>) -> libc::c_int { if !context.sql.is_open() { error!(context, "Import: Database not opened."); return 0; } - let real_spec: String; let mut read_cnt = 0; + let real_spec: String; + /* if `spec` is given, remember it for later usage; if it is not given, try to use the last one */ - if !spec.is_null() { - real_spec = to_string_lossy(spec); + if let Some(spec) = spec { + real_spec = spec.to_string(); context .sql .set_raw_config(context, "import_spec", Some(&real_spec)) @@ -174,7 +174,7 @@ fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int { 1 } -unsafe fn log_msg(context: &Context, prefix: impl AsRef, msg: &Message) { +fn log_msg(context: &Context, prefix: impl AsRef, msg: &Message) { let contact = Contact::get_by_id(context, msg.get_from_id()).expect("invalid contact"); let contact_name = contact.get_name(); let contact_id = contact.get_id(); @@ -219,7 +219,7 @@ unsafe fn log_msg(context: &Context, prefix: impl AsRef, msg: &Message) { ); } -unsafe fn log_msglist(context: &Context, msglist: &Vec) -> Result<(), Error> { +fn log_msglist(context: &Context, msglist: &Vec) -> Result<(), Error> { let mut lines_out = 0; for &msg_id in msglist { if msg_id.is_daymarker() { @@ -250,7 +250,7 @@ unsafe fn log_msglist(context: &Context, msglist: &Vec) -> Result<(), Err Ok(()) } -unsafe fn log_contactlist(context: &Context, contacts: &Vec) { +fn log_contactlist(context: &Context, contacts: &Vec) { let mut contacts = contacts.clone(); if !contacts.contains(&1) { contacts.push(1); @@ -302,7 +302,7 @@ fn chat_prefix(chat: &Chat) -> &'static str { chat.typ.into() } -pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::Error> { +pub fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::Error> { let chat_id = *context.cmdline_sel_chat_id.read().unwrap(); let mut sel_chat = if chat_id > 0 { Chat::load_from_db(context, chat_id).ok() @@ -313,11 +313,6 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E let mut args = line.splitn(3, ' '); let arg0 = args.next().unwrap_or_default(); let arg1 = args.next().unwrap_or_default(); - let arg1_c = if arg1.is_empty() { - std::ptr::null() - } else { - arg1.strdup() as *const _ - }; let arg2 = args.next().unwrap_or_default(); let blobdir = context.get_blobdir(); @@ -467,7 +462,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E ); } "poke" => { - ensure!(0 != poke_spec(context, arg1_c), "Poke failed"); + ensure!(0 != poke_spec(context, Some(arg1)), "Poke failed"); } "reset" => { ensure!(!arg1.is_empty(), "Argument missing: 1=jobs, 2=peerstates, 4=private keys, 8=rest but server config"); @@ -1008,7 +1003,5 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E _ => bail!("Unknown command: \"{}\" type ? for help.", arg0), } - free(arg1_c as *mut _); - Ok(()) } diff --git a/examples/repl/main.rs b/examples/repl/main.rs index bc7528c5d..178f4fb0d 100644 --- a/examples/repl/main.rs +++ b/examples/repl/main.rs @@ -403,7 +403,7 @@ fn main_0(args: Vec) -> Result<(), failure::Error> { // TODO: ignore "set mail_pw" rl.add_history_entry(line.as_str()); let ctx = ctx.clone(); - match unsafe { handle_cmd(line.trim(), ctx) } { + match handle_cmd(line.trim(), ctx) { Ok(ExitResult::Continue) => {} Ok(ExitResult::Exit) => break, Err(err) => println!("Error: {}", err), @@ -434,7 +434,7 @@ enum ExitResult { Exit, } -unsafe fn handle_cmd(line: &str, ctx: Arc>) -> Result { +fn handle_cmd(line: &str, ctx: Arc>) -> Result { let mut args = line.splitn(2, ' '); let arg0 = args.next().unwrap_or_default(); let arg1 = args.next().unwrap_or_default(); diff --git a/examples/simple.rs b/examples/simple.rs index 67c8fbbc7..71917e7c1 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -101,16 +101,6 @@ fn main() { thread::sleep(duration); - // let msglist = dc_get_chat_msgs(&ctx, chat_id, 0, 0); - // for i in 0..dc_array_get_cnt(msglist) { - // let msg_id = dc_array_get_id(msglist, i); - // let msg = dc_get_msg(context, msg_id); - // let text = CStr::from_ptr(dc_msg_get_text(msg)).unwrap(); - // println!("Message {}: {}\n", i + 1, text.to_str().unwrap()); - // dc_msg_unref(msg); - // } - // dc_array_unref(msglist); - println!("stopping threads"); *running.write().unwrap() = false; diff --git a/mmime/.circleci/config.yml b/mmime/.circleci/config.yml deleted file mode 100644 index 74a108d88..000000000 --- a/mmime/.circleci/config.yml +++ /dev/null @@ -1,42 +0,0 @@ -# copied from http://koushiro.me/2019/04/30/Building-and-Testing-Rust-projects-on-CircleCI/ - -version: 2.1 -jobs: - build: - docker: - - image: ubuntu:18.04 - - working_directory: ~/deltachat-core-rust - - steps: - - checkout - - - run: - name: Setup build environment - command: | - apt update - apt install -y curl build-essential autoconf libtool git python pkg-config - # this will pick default toolchain from `rust-toolchain` file - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --no-modify-path --default-toolchain none -y; - source $HOME/.cargo/env - no_output_timeout: 1800s - - - run: - name: Format - command: | - export PATH=~/.cargo/bin:$PATH - rustup component add rustfmt - cargo fmt -- --check - - - run: - name: Test - command: | - export PATH=~/.cargo/bin:$PATH - export RUST_BACKTRACE=1 - cargo test - -workflows: - version: 2.1 - build: - jobs: - - build diff --git a/mmime/Cargo.toml b/mmime/Cargo.toml deleted file mode 100644 index 6a3bcadde..000000000 --- a/mmime/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "mmime" -version = "0.1.2" -authors = ["dignifiedquire "] -edition = "2018" -license = "MIT OR Apache-2.0" -homepage = "https://github.com/deltachat/deltachat-core-rust" -repository = "https://github.com/deltachat/deltachat-core-rust" -readme = "README.md" -description = "Mime parsing for email" - - -keywords = ["mail", "mim", "email", "imap", "smtp"] -categories = ["std", "email"] - -[dependencies] -libc = "0.2.54" -charset = "0.1.2" -memmap = "0.7.0" -lazy_static = "1.3.0" -rand = "0.6.5" -chrono = "0.4.6" -hex = "0.4.0" diff --git a/mmime/LICENSE-APACHE b/mmime/LICENSE-APACHE deleted file mode 100644 index f8e5e5ea0..000000000 --- a/mmime/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. \ No newline at end of file diff --git a/mmime/LICENSE-MIT b/mmime/LICENSE-MIT deleted file mode 100644 index 468cd79a8..000000000 --- a/mmime/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/mmime/LICENSE.md b/mmime/LICENSE.md deleted file mode 100644 index 878517643..000000000 --- a/mmime/LICENSE.md +++ /dev/null @@ -1,4 +0,0 @@ -This library is primarly distributed under the terms of both the MIT license and -the Apache License (Version 2.0). - -See LICENSE-MIT and LICENSE-APACHE for details. diff --git a/mmime/README.md b/mmime/README.md deleted file mode 100644 index 16858f979..000000000 --- a/mmime/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# mmime - -[![CircleCI build status][circle-shield]][circle] [![Appveyor build status][appveyor-shield]][appveyor] [![License][license-shield]][license] - -> mmmmmmime parsing - -Base code was compiled using c2rust from libetpan. - - - -[circle-shield]: https://img.shields.io/circleci/project/github/dignifiedquire/mmime/master.svg?style=flat-square -[circle]: https://circleci.com/gh/dignifiedquire/mmime/ -[appveyor-shield]: https://ci.appveyor.com/api/projects/status/l26co5rba32knrlu/branch/master?style=flat-square -[appveyor]: https://ci.appveyor.com/project/dignifiedquire/mmime/branch/master -[license-shield]: https://img.shields.io/badge/License-MIT%2FApache2.0-green.svg?style=flat-square -[license]: https://github.com/rpgp/rpgp/blob/master/LICENSE.md diff --git a/mmime/src/charconv.rs b/mmime/src/charconv.rs deleted file mode 100644 index cbb6eca40..000000000 --- a/mmime/src/charconv.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::other::*; -use libc; -use std::ffi::{CStr, CString}; - -pub const MAIL_CHARCONV_ERROR_CONV: libc::c_uint = 3; -pub const MAIL_CHARCONV_ERROR_MEMORY: libc::c_uint = 2; -pub const MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET: libc::c_uint = 1; -pub const MAIL_CHARCONV_NO_ERROR: libc::c_uint = 0; - -pub unsafe fn charconv( - tocode: *const libc::c_char, - fromcode: *const libc::c_char, - s: *const libc::c_char, - length: size_t, - result: *mut *mut libc::c_char, -) -> libc::c_int { - assert!(!fromcode.is_null(), "invalid fromcode"); - assert!(!s.is_null(), "invalid input string"); - if let Some(encoding) = - charset::Charset::for_label(CStr::from_ptr(fromcode).to_string_lossy().as_bytes()) - { - let data = std::slice::from_raw_parts(s as *const u8, strlen(s)); - - let (res, _, _) = encoding.decode(data); - let res_c = CString::new(res.as_bytes()).unwrap_or_default(); - *result = strdup(res_c.as_ptr()) as *mut _; - - MAIL_CHARCONV_NO_ERROR as libc::c_int - } else { - MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET as libc::c_int - } -} diff --git a/mmime/src/chash.rs b/mmime/src/chash.rs deleted file mode 100644 index 301b35ae9..000000000 --- a/mmime/src/chash.rs +++ /dev/null @@ -1,427 +0,0 @@ -use libc; - -use crate::other::*; - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct chashdatum { - pub data: *mut libc::c_void, - pub len: libc::c_uint, -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct chash { - pub size: libc::c_uint, - pub count: libc::c_uint, - pub copyvalue: libc::c_int, - pub copykey: libc::c_int, - pub cells: *mut *mut chashcell, -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct chashcell { - pub func: libc::c_uint, - pub key: chashdatum, - pub value: chashdatum, - pub next: *mut chashcell, -} - -pub type chashiter = chashcell; -/* Allocates a new (empty) hash using this initial size and the given flags, - specifying which data should be copied in the hash. - CHASH_COPYNONE : Keys/Values are not copied. - CHASH_COPYKEY : Keys are dupped and freed as needed in the hash. - CHASH_COPYVALUE : Values are dupped and freed as needed in the hash. - CHASH_COPYALL : Both keys and values are dupped in the hash. -*/ -pub unsafe fn chash_new(mut size: libc::c_uint, mut flags: libc::c_int) -> *mut chash { - let mut h: *mut chash = 0 as *mut chash; - h = malloc(::std::mem::size_of::() as libc::size_t) as *mut chash; - if h.is_null() { - return 0 as *mut chash; - } - if size < 13i32 as libc::c_uint { - size = 13i32 as libc::c_uint - } - (*h).count = 0i32 as libc::c_uint; - (*h).cells = calloc( - size as libc::size_t, - ::std::mem::size_of::<*mut chashcell>() as libc::size_t, - ) as *mut *mut chashcell; - if (*h).cells.is_null() { - free(h as *mut libc::c_void); - return 0 as *mut chash; - } - (*h).size = size; - (*h).copykey = flags & 1i32; - (*h).copyvalue = flags & 2i32; - return h; -} - -/* Frees a hash */ -pub unsafe fn chash_free(mut hash: *mut chash) { - let mut indx: libc::c_uint = 0; - let mut iter: *mut chashiter = 0 as *mut chashiter; - let mut next: *mut chashiter = 0 as *mut chashiter; - indx = 0i32 as libc::c_uint; - while indx < (*hash).size { - iter = *(*hash).cells.offset(indx as isize); - while !iter.is_null() { - next = (*iter).next; - if 0 != (*hash).copykey { - free((*iter).key.data); - } - if 0 != (*hash).copyvalue { - free((*iter).value.data); - } - free(iter as *mut libc::c_void); - iter = next - } - indx = indx.wrapping_add(1) - } - free((*hash).cells as *mut libc::c_void); - free(hash as *mut libc::c_void); -} - -/* Removes all elements from a hash */ -pub unsafe fn chash_clear(mut hash: *mut chash) { - let mut indx: libc::c_uint = 0; - let mut iter: *mut chashiter = 0 as *mut chashiter; - let mut next: *mut chashiter = 0 as *mut chashiter; - indx = 0i32 as libc::c_uint; - while indx < (*hash).size { - iter = *(*hash).cells.offset(indx as isize); - while !iter.is_null() { - next = (*iter).next; - if 0 != (*hash).copykey { - free((*iter).key.data); - } - if 0 != (*hash).copyvalue { - free((*iter).value.data); - } - free(iter as *mut libc::c_void); - iter = next - } - indx = indx.wrapping_add(1) - } - memset( - (*hash).cells as *mut libc::c_void, - 0i32, - ((*hash).size as libc::size_t) - .wrapping_mul(::std::mem::size_of::<*mut chashcell>() as libc::size_t), - ); - (*hash).count = 0i32 as libc::c_uint; -} -/* Adds an entry in the hash table. -Length can be 0 if key/value are strings. -If an entry already exists for this key, it is replaced, and its value -is returned. Otherwise, the data pointer will be NULL and the length -field be set to TRUE or FALSe to indicate success or failure. */ -pub unsafe fn chash_set( - mut hash: *mut chash, - mut key: *mut chashdatum, - mut value: *mut chashdatum, - mut oldvalue: *mut chashdatum, -) -> libc::c_int { - let mut current_block: u64; - let mut func: libc::c_uint = 0; - let mut indx: libc::c_uint = 0; - let mut iter: *mut chashiter = 0 as *mut chashiter; - let mut cell: *mut chashiter = 0 as *mut chashiter; - let mut r: libc::c_int = 0; - if (*hash).count > (*hash).size.wrapping_mul(3i32 as libc::c_uint) { - r = chash_resize( - hash, - (*hash) - .count - .wrapping_div(3i32 as libc::c_uint) - .wrapping_mul(2i32 as libc::c_uint) - .wrapping_add(1i32 as libc::c_uint), - ); - if r < 0i32 { - current_block = 17701753836843438419; - } else { - current_block = 7095457783677275021; - } - } else { - current_block = 7095457783677275021; - } - match current_block { - 7095457783677275021 => { - func = chash_func((*key).data as *const libc::c_char, (*key).len); - indx = func.wrapping_rem((*hash).size); - iter = *(*hash).cells.offset(indx as isize); - loop { - if iter.is_null() { - current_block = 17788412896529399552; - break; - } - if (*iter).key.len == (*key).len - && (*iter).func == func - && 0 == memcmp((*iter).key.data, (*key).data, (*key).len as libc::size_t) - { - /* found, replacing entry */ - if 0 != (*hash).copyvalue { - let mut data: *mut libc::c_char = 0 as *mut libc::c_char; - data = chash_dup((*value).data, (*value).len); - if data.is_null() { - current_block = 17701753836843438419; - break; - } - free((*iter).value.data); - (*iter).value.data = data as *mut libc::c_void; - (*iter).value.len = (*value).len - } else { - if !oldvalue.is_null() { - (*oldvalue).data = (*iter).value.data; - (*oldvalue).len = (*iter).value.len - } - (*iter).value.data = (*value).data; - (*iter).value.len = (*value).len - } - if 0 == (*hash).copykey { - (*iter).key.data = (*key).data - } - if !oldvalue.is_null() { - (*oldvalue).data = (*value).data; - (*oldvalue).len = (*value).len - } - return 0i32; - } else { - iter = (*iter).next - } - } - match current_block { - 17701753836843438419 => {} - _ => { - if !oldvalue.is_null() { - (*oldvalue).data = 0 as *mut libc::c_void; - (*oldvalue).len = 0i32 as libc::c_uint - } - cell = malloc(::std::mem::size_of::() as libc::size_t) - as *mut chashcell; - if !cell.is_null() { - if 0 != (*hash).copykey { - (*cell).key.data = - chash_dup((*key).data, (*key).len) as *mut libc::c_void; - if (*cell).key.data.is_null() { - current_block = 4267898785354516004; - } else { - current_block = 7226443171521532240; - } - } else { - (*cell).key.data = (*key).data; - current_block = 7226443171521532240; - } - match current_block { - 7226443171521532240 => { - (*cell).key.len = (*key).len; - if 0 != (*hash).copyvalue { - (*cell).value.data = - chash_dup((*value).data, (*value).len) as *mut libc::c_void; - if (*cell).value.data.is_null() { - if 0 != (*hash).copykey { - free((*cell).key.data); - } - current_block = 4267898785354516004; - } else { - current_block = 6717214610478484138; - } - } else { - (*cell).value.data = (*value).data; - current_block = 6717214610478484138; - } - match current_block { - 4267898785354516004 => {} - _ => { - (*cell).value.len = (*value).len; - (*cell).func = func; - (*cell).next = *(*hash).cells.offset(indx as isize); - let ref mut fresh0 = *(*hash).cells.offset(indx as isize); - *fresh0 = cell; - (*hash).count = (*hash).count.wrapping_add(1); - return 0i32; - } - } - } - _ => {} - } - free(cell as *mut libc::c_void); - } - } - } - } - _ => {} - } - return -1i32; -} -#[inline] -unsafe fn chash_dup(mut data: *const libc::c_void, mut len: libc::c_uint) -> *mut libc::c_char { - let mut r: *mut libc::c_void = 0 as *mut libc::c_void; - r = malloc(len as libc::size_t) as *mut libc::c_char as *mut libc::c_void; - if r.is_null() { - return 0 as *mut libc::c_char; - } - memcpy(r, data, len as libc::size_t); - return r as *mut libc::c_char; -} - -#[inline] -unsafe fn chash_func(mut key: *const libc::c_char, mut len: libc::c_uint) -> libc::c_uint { - let mut c: libc::c_uint = 5381i32 as libc::c_uint; - let mut k: *const libc::c_char = key; - loop { - let fresh1 = len; - len = len.wrapping_sub(1); - if !(0 != fresh1) { - break; - } - let fresh2 = k; - k = k.offset(1); - c = (c << 5i32) - .wrapping_add(c) - .wrapping_add(*fresh2 as libc::c_uint) - } - return c; -} - -/* Resizes the hash table to the passed size. */ -pub unsafe fn chash_resize(mut hash: *mut chash, mut size: libc::c_uint) -> libc::c_int { - let mut cells: *mut *mut chashcell = 0 as *mut *mut chashcell; - let mut indx: libc::c_uint = 0; - let mut nindx: libc::c_uint = 0; - let mut iter: *mut chashiter = 0 as *mut chashiter; - let mut next: *mut chashiter = 0 as *mut chashiter; - if (*hash).size == size { - return 0i32; - } - cells = calloc( - size as libc::size_t, - ::std::mem::size_of::<*mut chashcell>() as libc::size_t, - ) as *mut *mut chashcell; - if cells.is_null() { - return -1i32; - } - indx = 0i32 as libc::c_uint; - while indx < (*hash).size { - iter = *(*hash).cells.offset(indx as isize); - while !iter.is_null() { - next = (*iter).next; - nindx = (*iter).func.wrapping_rem(size); - (*iter).next = *cells.offset(nindx as isize); - let ref mut fresh3 = *cells.offset(nindx as isize); - *fresh3 = iter; - iter = next - } - indx = indx.wrapping_add(1) - } - free((*hash).cells as *mut libc::c_void); - (*hash).size = size; - (*hash).cells = cells; - return 0i32; -} - -/* Retrieves the data associated to the key if it is found in the hash table. -The data pointer and the length will be NULL if not found*/ -pub unsafe fn chash_get( - mut hash: *mut chash, - mut key: *mut chashdatum, - mut result: *mut chashdatum, -) -> libc::c_int { - let mut func: libc::c_uint = 0; - let mut iter: *mut chashiter = 0 as *mut chashiter; - func = chash_func((*key).data as *const libc::c_char, (*key).len); - iter = *(*hash) - .cells - .offset(func.wrapping_rem((*hash).size) as isize); - while !iter.is_null() { - if (*iter).key.len == (*key).len - && (*iter).func == func - && 0 == memcmp((*iter).key.data, (*key).data, (*key).len as libc::size_t) - { - *result = (*iter).value; - return 0i32; - } - iter = (*iter).next - } - return -1i32; -} -/* Removes the entry associated to this key if it is found in the hash table, -and returns its contents if not dupped (otherwise, pointer will be NULL -and len TRUE). If entry is not found both pointer and len will be NULL. */ -pub unsafe fn chash_delete( - mut hash: *mut chash, - mut key: *mut chashdatum, - mut oldvalue: *mut chashdatum, -) -> libc::c_int { - /* chashdatum result = { NULL, TRUE }; */ - let mut func: libc::c_uint = 0; - let mut indx: libc::c_uint = 0; - let mut iter: *mut chashiter = 0 as *mut chashiter; - let mut old: *mut chashiter = 0 as *mut chashiter; - func = chash_func((*key).data as *const libc::c_char, (*key).len); - indx = func.wrapping_rem((*hash).size); - old = 0 as *mut chashiter; - iter = *(*hash).cells.offset(indx as isize); - while !iter.is_null() { - if (*iter).key.len == (*key).len - && (*iter).func == func - && 0 == memcmp((*iter).key.data, (*key).data, (*key).len as libc::size_t) - { - if !old.is_null() { - (*old).next = (*iter).next - } else { - let ref mut fresh4 = *(*hash).cells.offset(indx as isize); - *fresh4 = (*iter).next - } - if 0 != (*hash).copykey { - free((*iter).key.data); - } - if 0 != (*hash).copyvalue { - free((*iter).value.data); - } else if !oldvalue.is_null() { - (*oldvalue).data = (*iter).value.data; - (*oldvalue).len = (*iter).value.len - } - free(iter as *mut libc::c_void); - (*hash).count = (*hash).count.wrapping_sub(1); - return 0i32; - } - old = iter; - iter = (*iter).next - } - return -1i32; -} -/* Returns an iterator to the first non-empty entry of the hash table */ -pub unsafe fn chash_begin(mut hash: *mut chash) -> *mut chashiter { - let mut iter: *mut chashiter = 0 as *mut chashiter; - let mut indx: libc::c_uint = 0i32 as libc::c_uint; - iter = *(*hash).cells.offset(0isize); - while iter.is_null() { - indx = indx.wrapping_add(1); - if indx >= (*hash).size { - return 0 as *mut chashiter; - } - iter = *(*hash).cells.offset(indx as isize) - } - return iter; -} -/* Returns the next non-empty entry of the hash table */ -pub unsafe fn chash_next(mut hash: *mut chash, mut iter: *mut chashiter) -> *mut chashiter { - let mut indx: libc::c_uint = 0; - if iter.is_null() { - return 0 as *mut chashiter; - } - indx = (*iter).func.wrapping_rem((*hash).size); - iter = (*iter).next; - while iter.is_null() { - indx = indx.wrapping_add(1); - if indx >= (*hash).size { - return 0 as *mut chashiter; - } - iter = *(*hash).cells.offset(indx as isize) - } - return iter; -} diff --git a/mmime/src/clist.rs b/mmime/src/clist.rs deleted file mode 100644 index eb228d8b9..000000000 --- a/mmime/src/clist.rs +++ /dev/null @@ -1,202 +0,0 @@ -use libc; - -use crate::other::*; - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct clistcell { - pub data: *mut libc::c_void, - pub previous: *mut clistcell, - pub next: *mut clistcell, -} - -#[derive(Clone)] -#[repr(C)] -pub struct clist { - pub first: *mut clistcell, - pub last: *mut clistcell, - pub count: libc::c_int, -} - -impl Default for clist { - fn default() -> Self { - Self { - first: std::ptr::null_mut(), - last: std::ptr::null_mut(), - count: 0, - } - } -} - -impl Drop for clist { - fn drop(&mut self) { - unsafe { - let mut l1 = self.first; - while !l1.is_null() { - let l2 = (*l1).next; - free(l1 as *mut libc::c_void); - l1 = l2 - } - } - } -} - -pub type clistiter = clistcell; -pub struct CListIterator { - cur: *mut clistiter, -} -impl Iterator for CListIterator { - type Item = *mut libc::c_void; - fn next(&mut self) -> Option { - unsafe { - if self.cur.is_null() { - None - } else { - let data = (*self.cur).data; - self.cur = (*self.cur).next; - Some(data) - } - } - } -} - -impl IntoIterator for &clist { - type Item = *mut libc::c_void; - type IntoIter = CListIterator; - fn into_iter(self) -> Self::IntoIter { - return CListIterator { cur: self.first }; - } -} - -pub type clist_func = - Option ()>; - -/* Allocate a new pointer list */ -pub fn clist_new() -> *mut clist { - Box::into_raw(Box::new(Default::default())) -} -/* Destroys a list. Data pointed by data pointers is NOT freed. */ -pub unsafe fn clist_free(mut lst: *mut clist) { - Box::from_raw(lst); -} -/* Inserts this data pointer after the element pointed by the iterator */ -pub unsafe fn clist_insert_after( - mut lst: *mut clist, - mut iter: *mut clistiter, - mut data: *mut libc::c_void, -) -> libc::c_int { - let mut c: *mut clistcell = 0 as *mut clistcell; - c = malloc(::std::mem::size_of::() as libc::size_t) as *mut clistcell; - if c.is_null() { - return -1i32; - } - (*c).data = data; - (*lst).count += 1; - if (*lst).first == (*lst).last && (*lst).last.is_null() { - (*c).next = 0 as *mut clistcell; - (*c).previous = (*c).next; - (*lst).last = c; - (*lst).first = (*lst).last; - return 0i32; - } - if iter.is_null() { - (*c).previous = (*lst).last; - (*(*c).previous).next = c; - (*c).next = 0 as *mut clistcell; - (*lst).last = c; - return 0i32; - } - (*c).previous = iter; - (*c).next = (*iter).next; - if !(*c).next.is_null() { - (*(*c).next).previous = c - } else { - (*lst).last = c - } - (*(*c).previous).next = c; - return 0i32; -} -/* Deletes the element pointed by the iterator. -Returns an iterator to the next element. */ -pub unsafe fn clist_delete(mut lst: *mut clist, mut iter: *mut clistiter) -> *mut clistiter { - let mut ret: *mut clistiter = 0 as *mut clistiter; - if iter.is_null() { - return 0 as *mut clistiter; - } - if !(*iter).previous.is_null() { - (*(*iter).previous).next = (*iter).next - } else { - (*lst).first = (*iter).next - } - if !(*iter).next.is_null() { - (*(*iter).next).previous = (*iter).previous; - ret = (*iter).next - } else { - (*lst).last = (*iter).previous; - ret = 0 as *mut clistiter - } - free(iter as *mut libc::c_void); - (*lst).count -= 1; - return ret; -} -pub unsafe fn clist_foreach( - mut lst: *mut clist, - mut func: clist_func, - mut data: *mut libc::c_void, -) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*lst).first; - while !cur.is_null() { - func.expect("non-null function pointer")((*cur).data, data); - cur = (*cur).next - } -} - -pub unsafe fn clist_nth_data(mut lst: *mut clist, mut indx: libc::c_int) -> *mut libc::c_void { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = internal_clist_nth(lst, indx); - if cur.is_null() { - return 0 as *mut libc::c_void; - } - return (*cur).data; -} -#[inline] -unsafe fn internal_clist_nth(mut lst: *mut clist, mut indx: libc::c_int) -> *mut clistiter { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*lst).first; - while indx > 0i32 && !cur.is_null() { - cur = (*cur).next; - indx -= 1 - } - if cur.is_null() { - return 0 as *mut clistiter; - } - return cur; -} - -pub unsafe fn clist_nth(mut lst: *mut clist, mut indx: libc::c_int) -> *mut clistiter { - return internal_clist_nth(lst, indx); -} - -#[cfg(test)] -mod tests { - use super::*; - use std::ptr; - #[test] - fn test_clist_iterator() { - unsafe { - let mut c = clist_new(); - assert!(!c.is_null()); - clist_insert_after(c, ptr::null_mut(), clist_nth as _); - assert_eq!((*c).count, 1); - - /* Only one iteration */ - for data in &*c { - assert_eq!(data, clist_nth as _); - } - assert_eq!((*c).count, 1); - - clist_free(c); - } - } -} diff --git a/mmime/src/constants.rs b/mmime/src/constants.rs deleted file mode 100644 index 0f637f7bd..000000000 --- a/mmime/src/constants.rs +++ /dev/null @@ -1,71 +0,0 @@ -pub const MAIL_ERROR_SSL: libc::c_uint = 58; -pub const MAIL_ERROR_FOLDER: libc::c_uint = 57; -pub const MAIL_ERROR_UNABLE: libc::c_uint = 56; -pub const MAIL_ERROR_SYSTEM: libc::c_uint = 55; -pub const MAIL_ERROR_COMMAND: libc::c_uint = 54; -pub const MAIL_ERROR_SEND: libc::c_uint = 53; -pub const MAIL_ERROR_CHAR_ENCODING_FAILED: libc::c_uint = 52; -pub const MAIL_ERROR_SUBJECT_NOT_FOUND: libc::c_uint = 51; -/* 50 */ -pub const MAIL_ERROR_PROGRAM_ERROR: libc::c_uint = 50; -pub const MAIL_ERROR_NO_PERMISSION: libc::c_uint = 49; -pub const MAIL_ERROR_COMMAND_NOT_SUPPORTED: libc::c_uint = 48; -pub const MAIL_ERROR_NO_APOP: libc::c_uint = 47; -pub const MAIL_ERROR_READONLY: libc::c_uint = 46; -pub const MAIL_ERROR_FATAL: libc::c_uint = 45; -pub const MAIL_ERROR_CLOSE: libc::c_uint = 44; -pub const MAIL_ERROR_CAPABILITY: libc::c_uint = 43; -pub const MAIL_ERROR_PROTOCOL: libc::c_uint = 42; -/* misc errors */ -pub const MAIL_ERROR_MISC: libc::c_uint = 41; -/* 40 */ -pub const MAIL_ERROR_EXPUNGE: libc::c_uint = 40; -pub const MAIL_ERROR_NO_TLS: libc::c_uint = 39; -pub const MAIL_ERROR_CACHE_MISS: libc::c_uint = 38; -pub const MAIL_ERROR_STARTTLS: libc::c_uint = 37; -pub const MAIL_ERROR_MOVE: libc::c_uint = 36; -pub const MAIL_ERROR_FOLDER_NOT_FOUND: libc::c_uint = 35; -pub const MAIL_ERROR_REMOVE: libc::c_uint = 34; -pub const MAIL_ERROR_PART_NOT_FOUND: libc::c_uint = 33; -pub const MAIL_ERROR_INVAL: libc::c_uint = 32; -pub const MAIL_ERROR_PARSE: libc::c_uint = 31; -/* 30 */ -pub const MAIL_ERROR_MSG_NOT_FOUND: libc::c_uint = 30; -pub const MAIL_ERROR_DISKSPACE: libc::c_uint = 29; -pub const MAIL_ERROR_SEARCH: libc::c_uint = 28; -pub const MAIL_ERROR_STORE: libc::c_uint = 27; -pub const MAIL_ERROR_FETCH: libc::c_uint = 26; -pub const MAIL_ERROR_COPY: libc::c_uint = 25; -pub const MAIL_ERROR_APPEND: libc::c_uint = 24; -pub const MAIL_ERROR_LSUB: libc::c_uint = 23; -pub const MAIL_ERROR_LIST: libc::c_uint = 22; -pub const MAIL_ERROR_UNSUBSCRIBE: libc::c_uint = 21; -/* 20 */ -pub const MAIL_ERROR_SUBSCRIBE: libc::c_uint = 20; -pub const MAIL_ERROR_STATUS: libc::c_uint = 19; -pub const MAIL_ERROR_MEMORY: libc::c_uint = 18; -pub const MAIL_ERROR_SELECT: libc::c_uint = 17; -pub const MAIL_ERROR_EXAMINE: libc::c_uint = 16; -pub const MAIL_ERROR_CHECK: libc::c_uint = 15; -pub const MAIL_ERROR_RENAME: libc::c_uint = 14; -pub const MAIL_ERROR_NOOP: libc::c_uint = 13; -pub const MAIL_ERROR_LOGOUT: libc::c_uint = 12; -pub const MAIL_ERROR_DELETE: libc::c_uint = 11; -/* 10 */ -pub const MAIL_ERROR_CREATE: libc::c_uint = 10; -pub const MAIL_ERROR_LOGIN: libc::c_uint = 9; -pub const MAIL_ERROR_STREAM: libc::c_uint = 8; -pub const MAIL_ERROR_FILE: libc::c_uint = 7; -pub const MAIL_ERROR_BAD_STATE: libc::c_uint = 6; -pub const MAIL_ERROR_CONNECT: libc::c_uint = 5; -pub const MAIL_ERROR_UNKNOWN: libc::c_uint = 4; -pub const MAIL_ERROR_NOT_IMPLEMENTED: libc::c_uint = 3; -pub const MAIL_NO_ERROR_NON_AUTHENTICATED: libc::c_uint = 2; -pub const MAIL_NO_ERROR_AUTHENTICATED: libc::c_uint = 1; -pub const MAIL_NO_ERROR: libc::c_uint = 0; - -pub const MAILIMF_ERROR_FILE: libc::c_uint = 4; -pub const MAILIMF_ERROR_INVAL: libc::c_uint = 3; -pub const MAILIMF_ERROR_MEMORY: libc::c_uint = 2; -pub const MAILIMF_ERROR_PARSE: libc::c_uint = 1; -pub const MAILIMF_NO_ERROR: libc::c_uint = 0; diff --git a/mmime/src/display.rs b/mmime/src/display.rs deleted file mode 100644 index 3a895df7b..000000000 --- a/mmime/src/display.rs +++ /dev/null @@ -1,386 +0,0 @@ -use crate::clist::*; - -use crate::mailimf::types::*; -use crate::mailmime::types::*; - -use std::ffi::CStr; - -pub unsafe fn display_mime(mut mime: *mut Mailmime) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - println!("{}", (*mime).mm_type); - - match (*mime).mm_type as u32 { - MAILMIME_SINGLE => { - println!("single part"); - } - MAILMIME_MULTIPLE => { - println!("multipart"); - } - MAILMIME_MESSAGE => println!("message"), - _ => {} - } - if !(*mime).mm_mime_fields.is_null() { - if !(*(*(*mime).mm_mime_fields).fld_list).first.is_null() { - print!("MIME headers begin"); - display_mime_fields((*mime).mm_mime_fields); - println!("MIME headers end"); - } - } - display_mime_content((*mime).mm_content_type); - match (*mime).mm_type as u32 { - MAILMIME_SINGLE => { - display_mime_data((*mime).mm_data.mm_single); - } - MAILMIME_MULTIPLE => { - cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first; - while !cur.is_null() { - display_mime( - (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut Mailmime, - ); - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - } - MAILMIME_MESSAGE => { - if !(*mime).mm_data.mm_message.mm_fields.is_null() { - if !(*(*(*mime).mm_data.mm_message.mm_fields).fld_list) - .first - .is_null() - { - println!("headers begin"); - display_fields((*mime).mm_data.mm_message.mm_fields); - println!("headers end"); - } - if !(*mime).mm_data.mm_message.mm_msg_mime.is_null() { - display_mime((*mime).mm_data.mm_message.mm_msg_mime); - } - } - } - _ => {} - }; -} - -unsafe fn display_mime_content(mut content_type: *mut mailmime_content) { - print!("type: "); - display_mime_type((*content_type).ct_type); - println!( - "/{}", - CStr::from_ptr((*content_type).ct_subtype).to_str().unwrap() - ); -} -unsafe fn display_mime_type(mut type_0: *mut mailmime_type) { - match (*type_0).tp_type { - 1 => { - display_mime_discrete_type((*type_0).tp_data.tp_discrete_type); - } - 2 => { - display_mime_composite_type((*type_0).tp_data.tp_composite_type); - } - _ => {} - }; -} -unsafe fn display_mime_composite_type(mut ct: *mut mailmime_composite_type) { - match (*ct).ct_type { - 1 => { - print!("message"); - } - 2 => { - print!("multipart"); - } - 3 => { - print!("{}", CStr::from_ptr((*ct).ct_token).to_str().unwrap()); - } - _ => {} - }; -} -unsafe fn display_mime_discrete_type(mut discrete_type: *mut mailmime_discrete_type) { - match (*discrete_type).dt_type { - 1 => { - print!("text"); - } - 2 => { - print!("image"); - } - 3 => { - print!("audio"); - } - 4 => { - print!("video"); - } - 5 => { - print!("application"); - } - 6 => { - print!("{}", (*discrete_type).dt_extension as u8 as char); - } - _ => {} - }; -} -pub unsafe fn display_mime_data(mut data: *mut mailmime_data) { - match (*data).dt_type { - 0 => { - println!( - "data : {} bytes", - (*data).dt_data.dt_text.dt_length as libc::c_uint, - ); - } - 1 => { - println!( - "data (file) : {}", - CStr::from_ptr((*data).dt_data.dt_filename) - .to_str() - .unwrap() - ); - } - _ => {} - }; -} -unsafe fn display_mime_dsp_parm(mut param: *mut mailmime_disposition_parm) { - match (*param).pa_type { - 0 => { - println!( - "filename: {}", - CStr::from_ptr((*param).pa_data.pa_filename) - .to_str() - .unwrap() - ); - } - _ => {} - }; -} -unsafe fn display_mime_disposition(mut disposition: *mut mailmime_disposition) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*disposition).dsp_parms).first; - while !cur.is_null() { - let mut param: *mut mailmime_disposition_parm = 0 as *mut mailmime_disposition_parm; - param = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailmime_disposition_parm; - display_mime_dsp_parm(param); - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } -} -unsafe fn display_mime_field(mut field: *mut mailmime_field) { - match (*field).fld_type { - 1 => { - print!("content-type: "); - display_mime_content((*field).fld_data.fld_content); - println!(""); - } - 6 => { - display_mime_disposition((*field).fld_data.fld_disposition); - } - _ => {} - }; -} -unsafe fn display_mime_fields(mut fields: *mut mailmime_fields) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*fields).fld_list).first; - while !cur.is_null() { - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - field = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailmime_field; - display_mime_field(field); - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } -} -unsafe fn display_date_time(mut d: *mut mailimf_date_time) { - print!( - "{:02}/{:02}/{:02} {:02}:{:02}:{:02} +{:04}", - (*d).dt_day, - (*d).dt_month, - (*d).dt_year, - (*d).dt_hour, - (*d).dt_min, - (*d).dt_sec, - (*d).dt_zone, - ); -} -unsafe fn display_orig_date(mut orig_date: *mut mailimf_orig_date) { - display_date_time((*orig_date).dt_date_time); -} -unsafe fn display_mailbox(mut mb: *mut mailimf_mailbox) { - if !(*mb).mb_display_name.is_null() { - print!( - "{}", - CStr::from_ptr((*mb).mb_display_name).to_str().unwrap() - ); - } - print!("<{}>", CStr::from_ptr((*mb).mb_addr_spec).to_str().unwrap()); -} -unsafe fn display_mailbox_list(mut mb_list: *mut mailimf_mailbox_list) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*mb_list).mb_list).first; - while !cur.is_null() { - let mut mb: *mut mailimf_mailbox = 0 as *mut mailimf_mailbox; - mb = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailimf_mailbox; - display_mailbox(mb); - if !if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - .is_null() - { - print!(", "); - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } -} -unsafe fn display_group(mut group: *mut mailimf_group) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - print!( - "{}: ", - CStr::from_ptr((*group).grp_display_name).to_str().unwrap() - ); - cur = (*(*(*group).grp_mb_list).mb_list).first; - while !cur.is_null() { - let mut mb: *mut mailimf_mailbox = 0 as *mut mailimf_mailbox; - mb = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailimf_mailbox; - display_mailbox(mb); - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - print!("; "); -} -unsafe fn display_address(mut a: *mut mailimf_address) { - match (*a).ad_type { - 2 => { - display_group((*a).ad_data.ad_group); - } - 1 => { - display_mailbox((*a).ad_data.ad_mailbox); - } - _ => {} - }; -} -unsafe fn display_address_list(mut addr_list: *mut mailimf_address_list) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*addr_list).ad_list).first; - while !cur.is_null() { - let mut addr: *mut mailimf_address = 0 as *mut mailimf_address; - addr = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailimf_address; - display_address(addr); - if !if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - .is_null() - { - print!(", "); - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } -} -unsafe fn display_from(mut from: *mut mailimf_from) { - display_mailbox_list((*from).frm_mb_list); -} -unsafe fn display_to(mut to: *mut mailimf_to) { - display_address_list((*to).to_addr_list); -} -unsafe fn display_cc(mut cc: *mut mailimf_cc) { - display_address_list((*cc).cc_addr_list); -} -unsafe fn display_subject(mut subject: *mut mailimf_subject) { - print!("{}", CStr::from_ptr((*subject).sbj_value).to_str().unwrap()); -} -unsafe fn display_field(mut field: *mut mailimf_field) { - match (*field).fld_type { - 9 => { - print!("Date: "); - display_orig_date((*field).fld_data.fld_orig_date); - println!(""); - } - 10 => { - print!("From: "); - display_from((*field).fld_data.fld_from); - println!(""); - } - 13 => { - print!("To: "); - display_to((*field).fld_data.fld_to); - println!(""); - } - 14 => { - print!("Cc: "); - display_cc((*field).fld_data.fld_cc); - println!(""); - } - 19 => { - print!("Subject: "); - display_subject((*field).fld_data.fld_subject); - println!(""); - } - 16 => { - println!( - "Message-ID: {}", - CStr::from_ptr((*(*field).fld_data.fld_message_id).mid_value) - .to_str() - .unwrap(), - ); - } - _ => {} - }; -} -unsafe fn display_fields(mut fields: *mut mailimf_fields) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*fields).fld_list).first; - while !cur.is_null() { - let mut f: *mut mailimf_field = 0 as *mut mailimf_field; - f = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailimf_field; - display_field(f); - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } -} diff --git a/mmime/src/lib.rs b/mmime/src/lib.rs deleted file mode 100644 index 4b75c5165..000000000 --- a/mmime/src/lib.rs +++ /dev/null @@ -1,78 +0,0 @@ -#![deny(clippy::correctness)] -// TODO: make all of these errors, such that clippy actually passes. -#![warn(clippy::all, clippy::perf, clippy::not_unsafe_ptr_arg_deref)] -// This is nice, but for now just annoying. -#![allow(clippy::unreadable_literal)] -#![feature(ptr_wrapping_offset_from)] -#![allow(unused_attributes)] -#![allow(unused_variables)] -#![allow(mutable_transmutes)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(unused_assignments)] -#![allow(unused_mut)] -#![allow(unused_must_use)] -#![feature(extern_types)] -#![feature(const_raw_ptr_to_usize_cast)] - -pub mod charconv; -pub mod chash; -pub mod clist; -pub mod display; -pub mod mailimf; -pub mod mailmime; -pub mod mmapstring; -pub mod other; - -pub use self::charconv::*; -pub use self::chash::*; -pub use self::clist::*; -pub use self::display::*; -pub use self::mailimf::*; -pub use self::mailmime::*; -pub use self::mmapstring::*; -pub use self::other::*; - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn mailmime_parse_test() { - unsafe { - let data = "MIME-Version: 1.0\ - Content-Type: multipart/mixed; boundary=frontier\ - \ - This is a message with multiple parts in MIME format.\ - --frontier\ - Content-Type: text/plain\ - \ - This is the body of the message.\ - --frontier\ - Content-Type: application/octet-stream\ - Content-Transfer-Encoding: base64\ - \ - PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg\ - Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==\ - --frontier--"; - let c_data = std::ffi::CString::new(data).unwrap(); - - let mut current_index = 0; - let mut mime = std::ptr::null_mut(); - let res = crate::mailmime::content::mailmime_parse( - c_data.as_ptr(), - data.len() as usize, - &mut current_index, - &mut mime, - ); - - assert_eq!(res, MAIL_NO_ERROR as libc::c_int); - assert!(!mime.is_null()); - - display_mime(mime); - - mailmime::types::mailmime_free(mime); - } - } -} diff --git a/mmime/src/mailimf/mod.rs b/mmime/src/mailimf/mod.rs deleted file mode 100644 index 5740b6c40..000000000 --- a/mmime/src/mailimf/mod.rs +++ /dev/null @@ -1,5921 +0,0 @@ -pub mod types; -pub mod types_helper; -pub(crate) mod write_generic; - -use libc::{self, toupper}; - -use crate::clist::*; -use crate::mailimf::types::*; -use crate::mailmime::decode::*; -use crate::mailmime::types::*; -use crate::mmapstring::*; -use crate::other::*; - -pub const UNSTRUCTURED_START: libc::c_uint = 0; -pub const UNSTRUCTURED_LF: libc::c_uint = 2; -pub const UNSTRUCTURED_CR: libc::c_uint = 1; -pub const UNSTRUCTURED_WSP: libc::c_uint = 3; -pub const UNSTRUCTURED_OUT: libc::c_uint = 4; - -pub const STATE_ZONE_ERR: libc::c_uint = 4; -pub const STATE_ZONE_OK: libc::c_uint = 3; -pub const STATE_ZONE_3: libc::c_uint = 2; -pub const STATE_ZONE_2: libc::c_uint = 1; -pub const STATE_ZONE_CONT: libc::c_uint = 5; -pub const STATE_ZONE_1: libc::c_uint = 0; - -pub const MONTH_A: libc::c_uint = 5; -pub const MONTH_MA: libc::c_uint = 4; -pub const MONTH_M: libc::c_uint = 3; -pub const MONTH_JU: libc::c_uint = 2; -pub const MONTH_J: libc::c_uint = 1; -pub const MONTH_START: libc::c_uint = 0; -pub const DAY_NAME_S: libc::c_uint = 2; -pub const DAY_NAME_T: libc::c_uint = 1; -pub const DAY_NAME_START: libc::c_uint = 0; -pub const HEADER_RES: libc::c_uint = 5; -pub const HEADER_S: libc::c_uint = 4; -pub const HEADER_RE: libc::c_uint = 3; -pub const HEADER_R: libc::c_uint = 2; -pub const HEADER_C: libc::c_uint = 1; -pub const HEADER_START: libc::c_uint = 0; - -/* -day-name = "Mon" / "Tue" / "Wed" / "Thu" / - "Fri" / "Sat" / "Sun" -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_token_value { - pub value: libc::c_int, - pub str_0: *mut libc::c_char, -} - -/* - mailimf_message_parse will parse the given message - - @param message this is a string containing the message content - @param length this is the size of the given string - @param indx this is a pointer to the start of the message in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_message_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_message, -) -> libc::c_int { - let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; - let mut body: *mut mailimf_body = 0 as *mut mailimf_body; - let mut msg: *mut mailimf_message = 0 as *mut mailimf_message; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_fields_parse(message, length, &mut cur_token, &mut fields); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - r = mailimf_body_parse(message, length, &mut cur_token, &mut body); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - msg = mailimf_message_new(fields, body); - if msg.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - mailimf_body_free(body); - } else { - *indx = cur_token; - *result = msg; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_fields_free(fields); - } - } - return res; -} -/* - mailimf_body_parse will parse the given text part of a message - - @param message this is a string containing the message text part - @param length this is the size of the given string - @param indx this is a pointer to the start of the message text part in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_body_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_body, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut body: *mut mailimf_body = 0 as *mut mailimf_body; - cur_token = *indx; - body = mailimf_body_new( - message.offset(cur_token as isize), - length.wrapping_sub(cur_token), - ); - if body.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - cur_token = length; - *result = body; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailimf_crlf_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_char_parse(message, length, &mut cur_token, '\r' as i32 as libc::c_char); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_char_parse(message, length, &mut cur_token, '\n' as i32 as libc::c_char); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailimf_char_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut token: libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - cur_token = *indx; - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - if *message.offset(cur_token as isize) as libc::c_int == token as libc::c_int { - cur_token = cur_token.wrapping_add(1); - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } else { - return MAILIMF_ERROR_PARSE as libc::c_int; - }; -} -/* - mailimf_fields_parse will parse the given header fields - - @param message this is a string containing the header fields - @param length this is the size of the given string - @param indx this is a pointer to the start of the header fields in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_fields_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_fields, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut list: *mut clist = 0 as *mut clist; - let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - list = 0 as *mut clist; - r = mailimf_struct_multiple_parse( - message, - length, - &mut cur_token, - &mut list, - ::std::mem::transmute::< - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut *mut mailimf_field, - ) -> libc::c_int, - >, - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut libc::c_void, - ) -> libc::c_int, - >, - >(Some(mailimf_field_parse)), - ::std::mem::transmute::< - Option ()>, - Option libc::c_int>, - >(Some(mailimf_field_free)), - ); - /* - if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) { - res = r; - goto err; - } - */ - match r { - 0 => { - /* do nothing */ - current_block = 11050875288958768710; - } - 1 => { - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 6724962012950341805; - } else { - current_block = 11050875288958768710; - } - } - _ => { - res = r; - current_block = 6724962012950341805; - } - } - match current_block { - 11050875288958768710 => { - fields = mailimf_fields_new(list); - if fields.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !list.is_null() { - clist_foreach( - list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailimf_field_free)), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - } else { - *result = fields; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - _ => {} - } - return res; -} -unsafe fn mailimf_field_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_field, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut type_0: libc::c_int = 0; - let mut return_path: *mut mailimf_return = 0 as *mut mailimf_return; - let mut resent_date: *mut mailimf_orig_date = 0 as *mut mailimf_orig_date; - let mut resent_from: *mut mailimf_from = 0 as *mut mailimf_from; - let mut resent_sender: *mut mailimf_sender = 0 as *mut mailimf_sender; - let mut resent_to: *mut mailimf_to = 0 as *mut mailimf_to; - let mut resent_cc: *mut mailimf_cc = 0 as *mut mailimf_cc; - let mut resent_bcc: *mut mailimf_bcc = 0 as *mut mailimf_bcc; - let mut resent_msg_id: *mut mailimf_message_id = 0 as *mut mailimf_message_id; - let mut orig_date: *mut mailimf_orig_date = 0 as *mut mailimf_orig_date; - let mut from: *mut mailimf_from = 0 as *mut mailimf_from; - let mut sender: *mut mailimf_sender = 0 as *mut mailimf_sender; - let mut reply_to: *mut mailimf_reply_to = 0 as *mut mailimf_reply_to; - let mut to: *mut mailimf_to = 0 as *mut mailimf_to; - let mut cc: *mut mailimf_cc = 0 as *mut mailimf_cc; - let mut bcc: *mut mailimf_bcc = 0 as *mut mailimf_bcc; - let mut message_id: *mut mailimf_message_id = 0 as *mut mailimf_message_id; - let mut in_reply_to: *mut mailimf_in_reply_to = 0 as *mut mailimf_in_reply_to; - let mut references: *mut mailimf_references = 0 as *mut mailimf_references; - let mut subject: *mut mailimf_subject = 0 as *mut mailimf_subject; - let mut comments: *mut mailimf_comments = 0 as *mut mailimf_comments; - let mut keywords: *mut mailimf_keywords = 0 as *mut mailimf_keywords; - let mut optional_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field; - let mut field: *mut mailimf_field = 0 as *mut mailimf_field; - let mut guessed_type: libc::c_int = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - return_path = 0 as *mut mailimf_return; - resent_date = 0 as *mut mailimf_orig_date; - resent_from = 0 as *mut mailimf_from; - resent_sender = 0 as *mut mailimf_sender; - resent_to = 0 as *mut mailimf_to; - resent_cc = 0 as *mut mailimf_cc; - resent_bcc = 0 as *mut mailimf_bcc; - resent_msg_id = 0 as *mut mailimf_message_id; - orig_date = 0 as *mut mailimf_orig_date; - from = 0 as *mut mailimf_from; - sender = 0 as *mut mailimf_sender; - reply_to = 0 as *mut mailimf_reply_to; - to = 0 as *mut mailimf_to; - cc = 0 as *mut mailimf_cc; - bcc = 0 as *mut mailimf_bcc; - message_id = 0 as *mut mailimf_message_id; - in_reply_to = 0 as *mut mailimf_in_reply_to; - references = 0 as *mut mailimf_references; - subject = 0 as *mut mailimf_subject; - comments = 0 as *mut mailimf_comments; - keywords = 0 as *mut mailimf_keywords; - optional_field = 0 as *mut mailimf_optional_field; - guessed_type = guess_header_type(message, length, cur_token); - type_0 = MAILIMF_FIELD_NONE as libc::c_int; - match guessed_type { - 9 => { - r = mailimf_orig_date_parse(message, length, &mut cur_token, &mut orig_date); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILIMF_FIELD_ORIG_DATE as libc::c_int; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 10 => { - r = mailimf_from_parse(message, length, &mut cur_token, &mut from); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 11 => { - r = mailimf_sender_parse(message, length, &mut cur_token, &mut sender); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 12 => { - r = mailimf_reply_to_parse(message, length, &mut cur_token, &mut reply_to); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 13 => { - r = mailimf_to_parse(message, length, &mut cur_token, &mut to); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 14 => { - r = mailimf_cc_parse(message, length, &mut cur_token, &mut cc); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 15 => { - r = mailimf_bcc_parse(message, length, &mut cur_token, &mut bcc); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 16 => { - r = mailimf_message_id_parse(message, length, &mut cur_token, &mut message_id); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 17 => { - r = mailimf_in_reply_to_parse(message, length, &mut cur_token, &mut in_reply_to); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 18 => { - r = mailimf_references_parse(message, length, &mut cur_token, &mut references); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 19 => { - r = mailimf_subject_parse(message, length, &mut cur_token, &mut subject); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 20 => { - r = mailimf_comments_parse(message, length, &mut cur_token, &mut comments); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 21 => { - r = mailimf_keywords_parse(message, length, &mut cur_token, &mut keywords); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 1 => { - r = mailimf_return_parse(message, length, &mut cur_token, &mut return_path); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 2 => { - r = mailimf_resent_date_parse(message, length, &mut cur_token, &mut resent_date); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 3 => { - r = mailimf_resent_from_parse(message, length, &mut cur_token, &mut resent_from); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 4 => { - r = mailimf_resent_sender_parse(message, length, &mut cur_token, &mut resent_sender); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 5 => { - r = mailimf_resent_to_parse(message, length, &mut cur_token, &mut resent_to); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 6 => { - r = mailimf_resent_cc_parse(message, length, &mut cur_token, &mut resent_cc); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 7 => { - r = mailimf_resent_bcc_parse(message, length, &mut cur_token, &mut resent_bcc); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - 8 => { - r = mailimf_resent_msg_id_parse(message, length, &mut cur_token, &mut resent_msg_id); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 9846950269610550213; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9846950269610550213; - } else { - /* do nothing */ - res = r; - current_block = 10956553358380301606; - } - } - _ => { - current_block = 9846950269610550213; - } - } - match current_block { - 9846950269610550213 => { - if type_0 == MAILIMF_FIELD_NONE as libc::c_int { - r = mailimf_optional_field_parse( - message, - length, - &mut cur_token, - &mut optional_field, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 10956553358380301606; - } else { - type_0 = MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int; - current_block = 2920409193602730479; - } - } else { - current_block = 2920409193602730479; - } - match current_block { - 10956553358380301606 => {} - _ => { - field = mailimf_field_new( - type_0, - return_path, - resent_date, - resent_from, - resent_sender, - resent_to, - resent_cc, - resent_bcc, - resent_msg_id, - orig_date, - from, - sender, - reply_to, - to, - cc, - bcc, - message_id, - in_reply_to, - references, - subject, - comments, - keywords, - optional_field, - ); - if field.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !return_path.is_null() { - mailimf_return_free(return_path); - } - if !resent_date.is_null() { - mailimf_orig_date_free(resent_date); - } - if !resent_from.is_null() { - mailimf_from_free(resent_from); - } - if !resent_sender.is_null() { - mailimf_sender_free(resent_sender); - } - if !resent_to.is_null() { - mailimf_to_free(resent_to); - } - if !resent_cc.is_null() { - mailimf_cc_free(resent_cc); - } - if !resent_bcc.is_null() { - mailimf_bcc_free(resent_bcc); - } - if !resent_msg_id.is_null() { - mailimf_message_id_free(resent_msg_id); - } - if !orig_date.is_null() { - mailimf_orig_date_free(orig_date); - } - if !from.is_null() { - mailimf_from_free(from); - } - if !sender.is_null() { - mailimf_sender_free(sender); - } - if !reply_to.is_null() { - mailimf_reply_to_free(reply_to); - } - if !to.is_null() { - mailimf_to_free(to); - } - if !cc.is_null() { - mailimf_cc_free(cc); - } - if !bcc.is_null() { - mailimf_bcc_free(bcc); - } - if !message_id.is_null() { - mailimf_message_id_free(message_id); - } - if !in_reply_to.is_null() { - mailimf_in_reply_to_free(in_reply_to); - } - if !references.is_null() { - mailimf_references_free(references); - } - if !subject.is_null() { - mailimf_subject_free(subject); - } - if !comments.is_null() { - mailimf_comments_free(comments); - } - if !keywords.is_null() { - mailimf_keywords_free(keywords); - } - if !optional_field.is_null() { - mailimf_optional_field_free(optional_field); - } - } else { - *result = field; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - _ => {} - } - return res; -} -unsafe fn mailimf_optional_field_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_optional_field, -) -> libc::c_int { - let mut name: *mut libc::c_char = 0 as *mut libc::c_char; - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut optional_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_field_name_parse(message, length, &mut cur_token, &mut name); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstructured_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - optional_field = mailimf_optional_field_new(name, value); - if optional_field.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = optional_field; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_unstructured_free(value); - } - } - mailimf_field_name_free(name); - } - return res; -} -unsafe fn mailimf_unstrict_crlf_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - mailimf_cfws_parse(message, length, &mut cur_token); - r = mailimf_char_parse(message, length, &mut cur_token, '\r' as i32 as libc::c_char); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_char_parse(message, length, &mut cur_token, '\n' as i32 as libc::c_char); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailimf_cfws_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut has_comment: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - has_comment = 0i32; - loop { - r = mailimf_cfws_fws_comment_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - break; - } - return r; - } else { - has_comment = 1i32 - } - } - if 0 == has_comment { - r = mailimf_fws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -/* internal use, exported for MIME */ -pub unsafe fn mailimf_fws_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut final_token: size_t = 0; - let mut fws_1: libc::c_int = 0; - let mut fws_2: libc::c_int = 0; - let mut fws_3: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - fws_1 = 0i32; - loop { - r = mailimf_wsp_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - break; - } - return r; - } else { - fws_1 = 1i32 - } - } - final_token = cur_token; - r = mailimf_crlf_parse(message, length, &mut cur_token); - match r { - 0 => fws_2 = 1i32, - 1 => fws_2 = 0i32, - _ => return r, - } - fws_3 = 0i32; - if 0 != fws_2 { - loop { - r = mailimf_wsp_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - break; - } - return r; - } else { - fws_3 = 1i32 - } - } - } - if 0 == fws_1 && 0 == fws_3 { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - if 0 == fws_3 { - cur_token = final_token - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -#[inline] -unsafe fn mailimf_wsp_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - cur_token = *indx; - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - if *message.offset(cur_token as isize) as libc::c_int != ' ' as i32 - && *message.offset(cur_token as isize) as libc::c_int != '\t' as i32 - { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - cur_token = cur_token.wrapping_add(1); - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -/* -[FWS] comment -*/ -#[inline] -unsafe fn mailimf_cfws_fws_comment_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_fws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_comment_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -#[inline] -unsafe fn mailimf_comment_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_oparenth_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - loop { - r = mailimf_comment_fws_ccontent_parse(message, length, &mut cur_token); - if !(r != MAILIMF_NO_ERROR as libc::c_int) { - continue; - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - break; - } - return r; - } - r = mailimf_fws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_cparenth_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_cparenth_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_char_parse(message, length, indx, ')' as i32 as libc::c_char); -} -#[inline] -unsafe fn mailimf_comment_fws_ccontent_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_fws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_ccontent_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -#[inline] -unsafe fn mailimf_ccontent_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut ch: libc::c_char = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - if 0 != is_ctext(*message.offset(cur_token as isize)) { - cur_token = cur_token.wrapping_add(1) - } else { - r = mailimf_quoted_pair_parse(message, length, &mut cur_token, &mut ch); - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_comment_parse(message, length, &mut cur_token) - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -#[inline] -unsafe fn mailimf_quoted_pair_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - cur_token = *indx; - if cur_token.wrapping_add(1i32 as libc::size_t) >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - if *message.offset(cur_token as isize) as libc::c_int != '\\' as i32 { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - cur_token = cur_token.wrapping_add(1); - *result = *message.offset(cur_token as isize); - cur_token = cur_token.wrapping_add(1); - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -/* -ctext = NO-WS-CTL / ; Non white space controls - - %d33-39 / ; The rest of the US-ASCII - %d42-91 / ; characters not including "(", - %d93-126 ; ")", or "\" -*/ -#[inline] -unsafe fn is_ctext(mut ch: libc::c_char) -> libc::c_int { - let mut uch: libc::c_uchar = ch as libc::c_uchar; - if 0 != is_no_ws_ctl(ch) { - return 1i32; - } - if (uch as libc::c_int) < 33i32 { - return 0i32; - } - if uch as libc::c_int == 40i32 || uch as libc::c_int == 41i32 { - return 0i32; - } - if uch as libc::c_int == 92i32 { - return 0i32; - } - if uch as libc::c_int == 127i32 { - return 0i32; - } - return 1i32; -} -/* ************************************************************************ */ -/* RFC 2822 grammar */ -/* -NO-WS-CTL = %d1-8 / ; US-ASCII control characters - %d11 / ; that do not include the - %d12 / ; carriage return, line feed, - %d14-31 / ; and white space characters - %d127 -*/ -#[inline] -unsafe fn is_no_ws_ctl(mut ch: libc::c_char) -> libc::c_int { - if ch as libc::c_int == 9i32 || ch as libc::c_int == 10i32 || ch as libc::c_int == 13i32 { - return 0i32; - } - if ch as libc::c_int == 127i32 { - return 1i32; - } - return (ch as libc::c_int >= 1i32 && ch as libc::c_int <= 31i32) as libc::c_int; -} -unsafe fn mailimf_oparenth_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_char_parse(message, length, indx, '(' as i32 as libc::c_char); -} -unsafe fn mailimf_unstructured_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut state: libc::c_int = 0; - let mut begin: size_t = 0; - let mut terminal: size_t = 0; - let mut str: *mut libc::c_char = 0 as *mut libc::c_char; - cur_token = *indx; - loop { - let mut r: libc::c_int = 0; - r = mailimf_wsp_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - continue; - } - /* do nothing */ - if r == MAILIMF_ERROR_PARSE as libc::c_int { - break; - } - return r; - } - state = UNSTRUCTURED_START as libc::c_int; - begin = cur_token; - terminal = cur_token; - while state != UNSTRUCTURED_OUT as libc::c_int { - match state { - 0 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - terminal = cur_token; - match *message.offset(cur_token as isize) as libc::c_int { - 13 => state = UNSTRUCTURED_CR as libc::c_int, - 10 => state = UNSTRUCTURED_LF as libc::c_int, - _ => state = UNSTRUCTURED_START as libc::c_int, - } - } - 1 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match *message.offset(cur_token as isize) as libc::c_int { - 10 => state = UNSTRUCTURED_LF as libc::c_int, - _ => state = UNSTRUCTURED_START as libc::c_int, - } - } - 2 => { - if cur_token >= length { - state = UNSTRUCTURED_OUT as libc::c_int - } else { - match *message.offset(cur_token as isize) as libc::c_int { - 9 | 32 => state = UNSTRUCTURED_WSP as libc::c_int, - _ => state = UNSTRUCTURED_OUT as libc::c_int, - } - } - } - 3 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match *message.offset(cur_token as isize) as libc::c_int { - 13 => state = UNSTRUCTURED_CR as libc::c_int, - 10 => state = UNSTRUCTURED_LF as libc::c_int, - _ => state = UNSTRUCTURED_START as libc::c_int, - } - } - _ => {} - } - cur_token = cur_token.wrapping_add(1) - } - str = malloc( - terminal - .wrapping_sub(begin) - .wrapping_add(1i32 as libc::size_t), - ) as *mut libc::c_char; - if str.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - strncpy( - str, - message.offset(begin as isize), - terminal.wrapping_sub(begin), - ); - *str.offset(terminal.wrapping_sub(begin) as isize) = '\u{0}' as i32 as libc::c_char; - *indx = terminal; - *result = str; - return MAILIMF_NO_ERROR as libc::c_int; -} - -unsafe fn mailimf_colon_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_unstrict_char_parse(message, length, indx, ':' as i32 as libc::c_char); -} - -pub unsafe fn mailimf_unstrict_char_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut token: libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_char_parse(message, length, &mut cur_token, token); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_field_name_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut field_name: *mut libc::c_char = 0 as *mut libc::c_char; - let mut cur_token: size_t = 0; - let mut end: size_t = 0; - cur_token = *indx; - end = cur_token; - if end >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - while 0 != is_ftext(*message.offset(end as isize)) { - end = end.wrapping_add(1); - if end >= length { - break; - } - } - if end == cur_token { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - field_name = malloc( - end.wrapping_sub(cur_token) - .wrapping_add(1i32 as libc::size_t), - ) as *mut libc::c_char; - if field_name.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - strncpy( - field_name, - message.offset(cur_token as isize), - end.wrapping_sub(cur_token), - ); - *field_name.offset(end.wrapping_sub(cur_token) as isize) = '\u{0}' as i32 as libc::c_char; - cur_token = end; - *indx = cur_token; - *result = field_name; - return MAILIMF_NO_ERROR as libc::c_int; -} -/* -field-name = 1*ftext -*/ -#[inline] -unsafe fn is_ftext(mut ch: libc::c_char) -> libc::c_int { - let mut uch: libc::c_uchar = ch as libc::c_uchar; - if (uch as libc::c_int) < 33i32 { - return 0i32; - } - if uch as libc::c_int == 58i32 { - return 0i32; - } - return 1i32; -} -unsafe fn mailimf_resent_msg_id_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_message_id, -) -> libc::c_int { - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut cur_token: size_t = 0; - let mut message_id: *mut mailimf_message_id = 0 as *mut mailimf_message_id; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Resent-Message-ID\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Resent-Message-ID\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_msg_id_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - message_id = mailimf_message_id_new(value); - if message_id.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = message_id; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_msg_id_free(value); - } - } - } - return res; -} - -pub unsafe fn mailimf_msg_id_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut msg_id: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_lower_parse(message, length, &mut cur_token); - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_addr_spec_msg_id_parse(message, length, &mut cur_token, &mut msg_id); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - *result = msg_id; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } else if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_lower_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - current_block = 2668756484064249700; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 2668756484064249700; - } else { - // ok - res = r; - current_block = 9394595304415473402; - } - match current_block { - 9394595304415473402 => {} - _ => { - r = mailimf_addr_spec_msg_id_parse(message, length, &mut cur_token, &mut msg_id); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_greater_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - free(msg_id as *mut libc::c_void); - res = r - } else { - r = mailimf_greater_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int - || r == MAILIMF_ERROR_PARSE as libc::c_int - { - current_block = 6450636197030046351; - } else { - // ok - free(msg_id as *mut libc::c_void); - res = r; - current_block = 9394595304415473402; - } - match current_block { - 9394595304415473402 => {} - _ => { - *result = msg_id; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - } - } - } - return res; -} -unsafe fn mailimf_greater_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_unstrict_char_parse(message, length, indx, '>' as i32 as libc::c_char); -} -/* -for msg id -addr-spec = local-part "@" domain -*/ -unsafe fn mailimf_addr_spec_msg_id_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut addr_spec: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut begin: size_t = 0; - let mut end: size_t = 0; - let mut final_0: libc::c_int = 0; - let mut count: size_t = 0; - let mut src: *const libc::c_char = 0 as *const libc::c_char; - let mut dest: *mut libc::c_char = 0 as *mut libc::c_char; - let mut i: size_t = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - end = cur_token; - if end >= length { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - begin = cur_token; - final_0 = 0i32; - loop { - match *message.offset(end as isize) as libc::c_int { - 62 | 13 | 10 => final_0 = 1i32, - _ => {} - } - if 0 != final_0 { - break; - } - end = end.wrapping_add(1); - if end >= length { - break; - } - } - if end == begin { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - addr_spec = malloc( - end.wrapping_sub(cur_token) - .wrapping_add(1i32 as libc::size_t), - ) as *mut libc::c_char; - if addr_spec.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - count = end.wrapping_sub(cur_token); - src = message.offset(cur_token as isize); - dest = addr_spec; - i = 0i32 as size_t; - while i < count { - if *src as libc::c_int != ' ' as i32 && *src as libc::c_int != '\t' as i32 { - *dest = *src; - dest = dest.offset(1isize) - } - src = src.offset(1isize); - i = i.wrapping_add(1) - } - *dest = '\u{0}' as i32 as libc::c_char; - cur_token = end; - *result = addr_spec; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - return res; -} -unsafe fn mailimf_lower_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_unstrict_char_parse(message, length, indx, '<' as i32 as libc::c_char); -} - -pub unsafe fn mailimf_token_case_insensitive_len_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut token: *mut libc::c_char, - mut token_length: size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - cur_token = *indx; - if cur_token - .wrapping_add(token_length) - .wrapping_sub(1i32 as libc::size_t) - >= length - { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - if strncasecmp(message.offset(cur_token as isize), token, token_length) == 0i32 { - cur_token = (cur_token as libc::size_t).wrapping_add(token_length) as size_t as size_t; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } else { - return MAILIMF_ERROR_PARSE as libc::c_int; - }; -} -unsafe fn mailimf_resent_bcc_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_bcc, -) -> libc::c_int { - let mut addr_list: *mut mailimf_address_list = 0 as *mut mailimf_address_list; - let mut bcc: *mut mailimf_bcc = 0 as *mut mailimf_bcc; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - bcc = 0 as *mut mailimf_bcc; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Resent-Bcc\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Resent-Bcc\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - addr_list = 0 as *mut mailimf_address_list; - r = mailimf_address_list_parse(message, length, &mut cur_token, &mut addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - bcc = mailimf_bcc_new(addr_list); - if bcc.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = bcc; - *indx = cur_token; - return 1i32; - } - } - mailimf_address_list_free(addr_list); - } - } - } - return res; -} -/* - mailimf_address_list_parse will parse the given address list - - @param message this is a string containing the address list - @param length this is the size of the given string - @param indx this is a pointer to the start of the address list in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_address_list_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_address_list, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut list: *mut clist = 0 as *mut clist; - let mut address_list: *mut mailimf_address_list = 0 as *mut mailimf_address_list; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_struct_list_parse( - message, - length, - &mut cur_token, - &mut list, - ',' as i32 as libc::c_char, - ::std::mem::transmute::< - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut *mut mailimf_address, - ) -> libc::c_int, - >, - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut libc::c_void, - ) -> libc::c_int, - >, - >(Some(mailimf_address_parse)), - ::std::mem::transmute::< - Option ()>, - Option libc::c_int>, - >(Some(mailimf_address_free)), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - address_list = mailimf_address_list_new(list); - if address_list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - clist_foreach( - list, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailimf_address_free), - ), - 0 as *mut libc::c_void, - ); - clist_free(list); - } else { - *result = address_list; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} -/* - mailimf_address_parse will parse the given address - - @param message this is a string containing the address - @param length this is the size of the given string - @param indx this is a pointer to the start of the address in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_address_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_address, -) -> libc::c_int { - let mut type_0: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut mailbox: *mut mailimf_mailbox = 0 as *mut mailimf_mailbox; - let mut group: *mut mailimf_group = 0 as *mut mailimf_group; - let mut address: *mut mailimf_address = 0 as *mut mailimf_address; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - mailbox = 0 as *mut mailimf_mailbox; - group = 0 as *mut mailimf_group; - type_0 = MAILIMF_ADDRESS_ERROR as libc::c_int; - r = mailimf_group_parse(message, length, &mut cur_token, &mut group); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILIMF_ADDRESS_GROUP as libc::c_int - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_mailbox_parse(message, length, &mut cur_token, &mut mailbox); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILIMF_ADDRESS_MAILBOX as libc::c_int - } - } - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - address = mailimf_address_new(type_0, mailbox, group); - if address.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !mailbox.is_null() { - mailimf_mailbox_free(mailbox); - } - if !group.is_null() { - mailimf_group_free(group); - } - } else { - *result = address; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} -/* - mailimf_mailbox_parse will parse the given address - - @param message this is a string containing the mailbox - @param length this is the size of the given string - @param indx this is a pointer to the start of the mailbox in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_mailbox_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_mailbox, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut display_name: *mut libc::c_char = 0 as *mut libc::c_char; - let mut mailbox: *mut mailimf_mailbox = 0 as *mut mailimf_mailbox; - let mut addr_spec: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - display_name = 0 as *mut libc::c_char; - addr_spec = 0 as *mut libc::c_char; - r = mailimf_name_addr_parse( - message, - length, - &mut cur_token, - &mut display_name, - &mut addr_spec, - ); - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_addr_spec_parse(message, length, &mut cur_token, &mut addr_spec) - } - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - mailbox = mailimf_mailbox_new(display_name, addr_spec); - if mailbox.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !display_name.is_null() { - mailimf_display_name_free(display_name); - } - if !addr_spec.is_null() { - mailimf_addr_spec_free(addr_spec); - } - } else { - *result = mailbox; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} -unsafe fn mailimf_addr_spec_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut addr_spec: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut begin: size_t = 0; - let mut end: size_t = 0; - let mut final_0: libc::c_int = 0; - let mut count: size_t = 0; - let mut src: *const libc::c_char = 0 as *const libc::c_char; - let mut dest: *mut libc::c_char = 0 as *mut libc::c_char; - let mut i: size_t = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - end = cur_token; - if end >= length { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - begin = cur_token; - final_0 = 0i32; - loop { - match *message.offset(end as isize) as libc::c_int { - 62 | 44 | 13 | 10 | 40 | 41 | 58 | 59 => final_0 = 1i32, - _ => {} - } - if 0 != final_0 { - break; - } - end = end.wrapping_add(1); - if end >= length { - break; - } - } - if end == begin { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - addr_spec = malloc( - end.wrapping_sub(cur_token) - .wrapping_add(1i32 as libc::size_t), - ) as *mut libc::c_char; - if addr_spec.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - count = end.wrapping_sub(cur_token); - src = message.offset(cur_token as isize); - dest = addr_spec; - i = 0i32 as size_t; - while i < count { - if *src as libc::c_int != ' ' as i32 && *src as libc::c_int != '\t' as i32 { - *dest = *src; - dest = dest.offset(1isize) - } - src = src.offset(1isize); - i = i.wrapping_add(1) - } - *dest = '\u{0}' as i32 as libc::c_char; - cur_token = end; - *result = addr_spec; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - return res; -} -unsafe fn mailimf_name_addr_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut pdisplay_name: *mut *mut libc::c_char, - mut pangle_addr: *mut *mut libc::c_char, -) -> libc::c_int { - let mut display_name: *mut libc::c_char = 0 as *mut libc::c_char; - let mut angle_addr: *mut libc::c_char = 0 as *mut libc::c_char; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - display_name = 0 as *mut libc::c_char; - angle_addr = 0 as *mut libc::c_char; - r = mailimf_display_name_parse(message, length, &mut cur_token, &mut display_name); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - r = mailimf_angle_addr_parse(message, length, &mut cur_token, &mut angle_addr); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - if !display_name.is_null() { - mailimf_display_name_free(display_name); - } - } else { - *pdisplay_name = display_name; - *pangle_addr = angle_addr; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} -unsafe fn mailimf_angle_addr_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut addr_spec: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_lower_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_addr_spec_parse(message, length, &mut cur_token, &mut addr_spec); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_greater_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - free(addr_spec as *mut libc::c_void); - return r; - } - *result = addr_spec; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_display_name_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - return mailimf_phrase_parse(message, length, indx, result); -} -unsafe fn mailimf_phrase_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut current_block: u64; - let mut gphrase: *mut MMAPString = 0 as *mut MMAPString; - let mut word: *mut libc::c_char = 0 as *mut libc::c_char; - let mut first: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut str: *mut libc::c_char = 0 as *mut libc::c_char; - let mut has_missing_closing_quote: libc::c_int = 0; - cur_token = *indx; - has_missing_closing_quote = 0i32; - gphrase = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char); - if gphrase.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - first = 1i32; - loop { - let mut missing_quote: libc::c_int = 0i32; - r = mailimf_fws_word_parse( - message, - length, - &mut cur_token, - &mut word, - &mut missing_quote, - ); - if 0 != missing_quote { - has_missing_closing_quote = 1i32 - } - if r == MAILIMF_NO_ERROR as libc::c_int { - if 0 == first { - if mmap_string_append_c(gphrase, ' ' as i32 as libc::c_char).is_null() { - mailimf_word_free(word); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 17261756273978092585; - break; - } - } - if mmap_string_append(gphrase, word).is_null() { - mailimf_word_free(word); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 17261756273978092585; - break; - } else { - mailimf_word_free(word); - first = 0i32 - } - } else { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 11636175345244025579; - break; - } - res = r; - current_block = 17261756273978092585; - break; - } - } - match current_block { - 11636175345244025579 => { - if 0 != first { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - if 0 != has_missing_closing_quote { - r = mailimf_char_parse( - message, - length, - &mut cur_token, - '\"' as i32 as libc::c_char, - ) - } - str = strdup((*gphrase).str_0); - if str.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - mmap_string_free(gphrase); - *result = str; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - _ => {} - } - mmap_string_free(gphrase); - } - return res; -} - -pub unsafe fn mailimf_fws_word_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, - mut p_missing_closing_quote: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut word: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - let mut missing_closing_quote: libc::c_int = 0; - cur_token = *indx; - missing_closing_quote = 0i32; - r = mailimf_fws_atom_for_word_parse( - message, - length, - &mut cur_token, - &mut word, - &mut missing_closing_quote, - ); - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_fws_quoted_string_parse(message, length, &mut cur_token, &mut word) - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *result = word; - *indx = cur_token; - *p_missing_closing_quote = missing_closing_quote; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailimf_fws_quoted_string_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut gstr: *mut MMAPString = 0 as *mut MMAPString; - let mut ch: libc::c_char = 0; - let mut str: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_fws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - r = mailimf_dquote_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - gstr = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char); - if gstr.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - loop { - r = mailimf_fws_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - if mmap_string_append_c(gstr, ' ' as i32 as libc::c_char).is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 15096897878952122875; - break; - } - } else if r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r; - current_block = 15096897878952122875; - break; - } - r = mailimf_qcontent_parse(message, length, &mut cur_token, &mut ch); - if r == MAILIMF_NO_ERROR as libc::c_int { - if !mmap_string_append_c(gstr, ch).is_null() { - continue; - } - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 15096897878952122875; - break; - } else { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 5494826135382683477; - break; - } - res = r; - current_block = 15096897878952122875; - break; - } - } - match current_block { - 5494826135382683477 => { - r = mailimf_dquote_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - str = strdup((*gstr).str_0); - if str.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - mmap_string_free(gstr); - *indx = cur_token; - *result = str; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - _ => {} - } - mmap_string_free(gstr); - } - } - } - return res; -} -unsafe fn mailimf_dquote_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_char_parse(message, length, indx, '\"' as i32 as libc::c_char); -} -unsafe fn mailimf_qcontent_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut ch: libc::c_char = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - if 0 != is_qtext(*message.offset(cur_token as isize)) { - ch = *message.offset(cur_token as isize); - cur_token = cur_token.wrapping_add(1) - } else { - r = mailimf_quoted_pair_parse(message, length, &mut cur_token, &mut ch); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - *result = ch; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -/* -dot-atom = [CFWS] dot-atom-text [CFWS] -*/ -/* -dot-atom-text = 1*atext *("." 1*atext) -*/ -/* -qtext = NO-WS-CTL / ; Non white space controls - - %d33 / ; The rest of the US-ASCII - %d35-91 / ; characters not including "\" - %d93-126 ; or the quote character -*/ -#[inline] -unsafe fn is_qtext(mut ch: libc::c_char) -> libc::c_int { - let mut uch: libc::c_uchar = ch as libc::c_uchar; - if 0 != is_no_ws_ctl(ch) { - return 1i32; - } - if (uch as libc::c_int) < 33i32 { - return 0i32; - } - if uch as libc::c_int == 34i32 { - return 0i32; - } - if uch as libc::c_int == 92i32 { - return 0i32; - } - if uch as libc::c_int == 127i32 { - return 0i32; - } - return 1i32; -} -unsafe fn mailimf_fws_atom_for_word_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, - mut p_missing_closing_quote: *mut libc::c_int, -) -> libc::c_int { - let mut end: size_t = 0; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut word: *mut mailmime_encoded_word = 0 as *mut mailmime_encoded_word; - let mut has_fwd: libc::c_int = 0; - let mut missing_closing_quote: libc::c_int = 0; - let mut atom: *mut libc::c_char = 0 as *mut libc::c_char; - cur_token = *indx; - missing_closing_quote = 0i32; - r = mailimf_fws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - end = cur_token; - r = mailmime_encoded_word_parse( - message, - length, - &mut cur_token, - &mut word, - &mut has_fwd, - &mut missing_closing_quote, - ); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - return mailimf_fws_atom_parse(message, length, indx, result); - } - mailmime_encoded_word_free(word); - atom = malloc( - cur_token - .wrapping_sub(end) - .wrapping_add(1i32 as libc::size_t), - ) as *mut libc::c_char; - if atom.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - strncpy( - atom, - message.offset(end as isize), - cur_token.wrapping_sub(end), - ); - *atom.offset(cur_token.wrapping_sub(end) as isize) = '\u{0}' as i32 as libc::c_char; - *result = atom; - *indx = cur_token; - *p_missing_closing_quote = missing_closing_quote; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - return res; -} - -pub unsafe fn mailimf_fws_atom_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut atom: *mut libc::c_char = 0 as *mut libc::c_char; - let mut end: size_t = 0; - cur_token = *indx; - r = mailimf_fws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - end = cur_token; - if end >= length { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - while 0 != is_atext(*message.offset(end as isize)) { - end = end.wrapping_add(1); - if end >= length { - break; - } - } - if end == cur_token { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - atom = malloc( - end.wrapping_sub(cur_token) - .wrapping_add(1i32 as libc::size_t), - ) as *mut libc::c_char; - if atom.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - strncpy( - atom, - message.offset(cur_token as isize), - end.wrapping_sub(cur_token), - ); - *atom.offset(end.wrapping_sub(cur_token) as isize) = - '\u{0}' as i32 as libc::c_char; - cur_token = end; - *indx = cur_token; - *result = atom; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - return res; -} -/* -atext = ALPHA / DIGIT / ; Any character except controls, - "!" / "#" / ; SP, and specials. - "$" / "%" / ; Used for atoms - "&" / "'" / - "*" / "+" / - "-" / "/" / - "=" / "?" / - "^" / "_" / - "`" / "{" / - "|" / "}" / - "~" -*/ -#[inline] -unsafe fn is_atext(mut ch: libc::c_char) -> libc::c_int { - match ch as libc::c_int { - 32 | 9 | 10 | 13 | 60 | 62 | 44 | 34 | 58 | 59 => return 0i32, - _ => return 1i32, - }; -} -unsafe fn mailimf_group_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_group, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut display_name: *mut libc::c_char = 0 as *mut libc::c_char; - let mut mailbox_list: *mut mailimf_mailbox_list = 0 as *mut mailimf_mailbox_list; - let mut group: *mut mailimf_group = 0 as *mut mailimf_group; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut list: *mut clist = 0 as *mut clist; - cur_token = *indx; - mailbox_list = 0 as *mut mailimf_mailbox_list; - r = mailimf_display_name_parse(message, length, &mut cur_token, &mut display_name); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_mailbox_list_parse(message, length, &mut cur_token, &mut mailbox_list); - match r { - 0 => { - current_block = 1608152415753874203; - } - 1 => { - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - res = r; - current_block = 14904789583098922708; - } else { - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14904789583098922708; - } else { - mailbox_list = mailimf_mailbox_list_new(list); - if mailbox_list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - clist_free(list); - current_block = 14904789583098922708; - } else { - current_block = 1608152415753874203; - } - } - } - } - _ => { - res = r; - current_block = 14904789583098922708; - } - } - match current_block { - 14904789583098922708 => {} - _ => { - r = mailimf_semi_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - group = mailimf_group_new(display_name, mailbox_list); - if group.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *indx = cur_token; - *result = group; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - if !mailbox_list.is_null() { - mailimf_mailbox_list_free(mailbox_list); - } - } - } - } - mailimf_display_name_free(display_name); - } - return res; -} - -unsafe fn mailimf_semi_colon_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_unstrict_char_parse(message, length, indx, ';' as i32 as libc::c_char); -} - -/* - mailimf_mailbox_list_parse will parse the given mailbox list - - @param message this is a string containing the mailbox list - @param length this is the size of the given string - @param indx this is a pointer to the start of the mailbox list in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_mailbox_list_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_mailbox_list, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut list: *mut clist = 0 as *mut clist; - let mut mailbox_list: *mut mailimf_mailbox_list = 0 as *mut mailimf_mailbox_list; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_struct_list_parse( - message, - length, - &mut cur_token, - &mut list, - ',' as i32 as libc::c_char, - ::std::mem::transmute::< - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut *mut mailimf_mailbox, - ) -> libc::c_int, - >, - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut libc::c_void, - ) -> libc::c_int, - >, - >(Some(mailimf_mailbox_parse)), - ::std::mem::transmute::< - Option ()>, - Option libc::c_int>, - >(Some(mailimf_mailbox_free)), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - mailbox_list = mailimf_mailbox_list_new(list); - if mailbox_list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - clist_foreach( - list, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailimf_mailbox_free), - ), - 0 as *mut libc::c_void, - ); - clist_free(list); - } else { - *result = mailbox_list; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} -unsafe fn mailimf_struct_list_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut clist, - mut symbol: libc::c_char, - mut parser: Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut libc::c_void, - ) -> libc::c_int, - >, - mut destructor: Option libc::c_int>, -) -> libc::c_int { - let mut current_block: u64; - let mut struct_list: *mut clist = 0 as *mut clist; - let mut cur_token: size_t = 0; - let mut value: *mut libc::c_void = 0 as *mut libc::c_void; - let mut final_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = parser.expect("non-null function pointer")( - message, - length, - &mut cur_token, - &mut value as *mut *mut libc::c_void as *mut libc::c_void, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - struct_list = clist_new(); - if struct_list.is_null() { - destructor.expect("non-null function pointer")(value); - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - r = clist_insert_after(struct_list, (*struct_list).last, value); - if r < 0i32 { - destructor.expect("non-null function pointer")(value); - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - final_token = cur_token; - loop { - r = mailimf_unstrict_char_parse(message, length, &mut cur_token, symbol); - if r != MAILIMF_NO_ERROR as libc::c_int { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9853141518545631134; - break; - } - res = r; - current_block = 17524159567010234572; - break; - } else { - r = parser.expect("non-null function pointer")( - message, - length, - &mut cur_token, - &mut value as *mut *mut libc::c_void as *mut libc::c_void, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 9853141518545631134; - break; - } - res = r; - current_block = 17524159567010234572; - break; - } else { - r = clist_insert_after(struct_list, (*struct_list).last, value); - if r < 0i32 { - destructor.expect("non-null function pointer")(value); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 17524159567010234572; - break; - } else { - final_token = cur_token - } - } - } - } - match current_block { - 17524159567010234572 => {} - _ => { - *result = struct_list; - *indx = final_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - clist_foreach( - struct_list, - ::std::mem::transmute::< - Option libc::c_int>, - clist_func, - >(destructor), - 0 as *mut libc::c_void, - ); - clist_free(struct_list); - } - } - return res; -} -unsafe fn mailimf_resent_cc_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_cc, -) -> libc::c_int { - let mut addr_list: *mut mailimf_address_list = 0 as *mut mailimf_address_list; - let mut cc: *mut mailimf_cc = 0 as *mut mailimf_cc; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Resent-Cc\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Resent-Cc\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_address_list_parse(message, length, &mut cur_token, &mut addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - cc = mailimf_cc_new(addr_list); - if cc.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = cc; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_address_list_free(addr_list); - } - } - } - return res; -} -unsafe fn mailimf_resent_to_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_to, -) -> libc::c_int { - let mut addr_list: *mut mailimf_address_list = 0 as *mut mailimf_address_list; - let mut to: *mut mailimf_to = 0 as *mut mailimf_to; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Resent-To\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Resent-To\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_address_list_parse(message, length, &mut cur_token, &mut addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - to = mailimf_to_new(addr_list); - if to.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = to; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_address_list_free(addr_list); - } - } - } - return res; -} -unsafe fn mailimf_resent_sender_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_sender, -) -> libc::c_int { - let mut mb: *mut mailimf_mailbox = 0 as *mut mailimf_mailbox; - let mut sender: *mut mailimf_sender = 0 as *mut mailimf_sender; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = length; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Resent-Sender\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Resent-Sender\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_mailbox_parse(message, length, &mut cur_token, &mut mb); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - sender = mailimf_sender_new(mb); - if sender.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = sender; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_mailbox_free(mb); - } - } - } - return res; -} -unsafe fn mailimf_resent_from_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_from, -) -> libc::c_int { - let mut mb_list: *mut mailimf_mailbox_list = 0 as *mut mailimf_mailbox_list; - let mut from: *mut mailimf_from = 0 as *mut mailimf_from; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Resent-From\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Resent-From\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_mailbox_list_parse(message, length, &mut cur_token, &mut mb_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - from = mailimf_from_new(mb_list); - if from.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = from; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_mailbox_list_free(mb_list); - } - } - } - return res; -} -unsafe fn mailimf_resent_date_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_orig_date, -) -> libc::c_int { - let mut orig_date: *mut mailimf_orig_date = 0 as *mut mailimf_orig_date; - let mut date_time: *mut mailimf_date_time = 0 as *mut mailimf_date_time; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Resent-Date\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Resent-Date\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_date_time_parse(message, length, &mut cur_token, &mut date_time); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - orig_date = mailimf_orig_date_new(date_time); - if orig_date.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = orig_date; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_date_time_free(date_time); - } - } - } - return res; -} -/* - mailimf_date_time_parse will parse the given RFC 2822 date - - @param message this is a string containing the date - @param length this is the size of the given string - @param indx this is a pointer to the start of the date in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_date_time_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_date_time, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut day_of_week: libc::c_int = 0; - let mut date_time: *mut mailimf_date_time = 0 as *mut mailimf_date_time; - let mut day: libc::c_int = 0; - let mut month: libc::c_int = 0; - let mut year: libc::c_int = 0; - let mut hour: libc::c_int = 0; - let mut min: libc::c_int = 0; - let mut sec: libc::c_int = 0; - let mut zone: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - day_of_week = -1i32; - r = mailimf_day_of_week_parse(message, length, &mut cur_token, &mut day_of_week); - if r == MAILIMF_NO_ERROR as libc::c_int { - r = mailimf_comma_parse(message, length, &mut cur_token); - if !(r == MAILIMF_ERROR_PARSE as libc::c_int) { - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - } else if r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - day = 0i32; - month = 0i32; - year = 0i32; - r = mailimf_date_parse( - message, - length, - &mut cur_token, - &mut day, - &mut month, - &mut year, - ); - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_broken_date_parse( - message, - length, - &mut cur_token, - &mut day, - &mut month, - &mut year, - ) - } else if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_fws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - hour = 0i32; - min = 0i32; - sec = 0i32; - zone = 0i32; - r = mailimf_time_parse( - message, - length, - &mut cur_token, - &mut hour, - &mut min, - &mut sec, - &mut zone, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - date_time = mailimf_date_time_new(day, month, year, hour, min, sec, zone); - if date_time.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - *indx = cur_token; - *result = date_time; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_time_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut phour: *mut libc::c_int, - mut pmin: *mut libc::c_int, - mut psec: *mut libc::c_int, - mut pzone: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut hour: libc::c_int = 0; - let mut min: libc::c_int = 0; - let mut sec: libc::c_int = 0; - let mut zone: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_time_of_day_parse( - message, - length, - &mut cur_token, - &mut hour, - &mut min, - &mut sec, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_fws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_zone_parse(message, length, &mut cur_token, &mut zone); - if !(r == MAILIMF_NO_ERROR as libc::c_int) { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - zone = 0i32 - } else { - return r; - } - } - *phour = hour; - *pmin = min; - *psec = sec; - *pzone = zone; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_zone_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut zone: libc::c_int = 0; - let mut sign: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut value: uint32_t = 0; - cur_token = *indx; - if cur_token.wrapping_add(1i32 as libc::size_t) < length { - if *message.offset(cur_token as isize) as libc::c_int == 'U' as i32 - && *message.offset(cur_token.wrapping_add(1i32 as libc::size_t) as isize) as libc::c_int - == 'T' as i32 - { - *result = 1i32; - *indx = cur_token.wrapping_add(2i32 as libc::size_t); - return MAILIMF_NO_ERROR as libc::c_int; - } - } - zone = 0i32; - if cur_token.wrapping_add(2i32 as libc::size_t) < length { - let mut state: libc::c_int = 0; - state = STATE_ZONE_1 as libc::c_int; - while state <= 2i32 { - match state { - 0 => match *message.offset(cur_token as isize) as libc::c_int { - 71 => { - if *message.offset(cur_token.wrapping_add(1i32 as libc::size_t) as isize) - as libc::c_int - == 'M' as i32 - && *message - .offset(cur_token.wrapping_add(2i32 as libc::size_t) as isize) - as libc::c_int - == 'T' as i32 - { - if cur_token.wrapping_add(3i32 as libc::size_t) < length - && (*message - .offset(cur_token.wrapping_add(3i32 as libc::size_t) as isize) - as libc::c_int - == '+' as i32 - || *message.offset( - cur_token.wrapping_add(3i32 as libc::size_t) as isize - ) as libc::c_int - == '-' as i32) - { - cur_token = (cur_token as libc::size_t) - .wrapping_add(3i32 as libc::size_t) - as size_t as size_t; - state = STATE_ZONE_CONT as libc::c_int - } else { - zone = 0i32; - state = STATE_ZONE_OK as libc::c_int - } - } else { - state = STATE_ZONE_ERR as libc::c_int - } - } - 69 => { - zone = -5i32; - state = STATE_ZONE_2 as libc::c_int - } - 67 => { - zone = -6i32; - state = STATE_ZONE_2 as libc::c_int - } - 77 => { - zone = -7i32; - state = STATE_ZONE_2 as libc::c_int - } - 80 => { - zone = -8i32; - state = STATE_ZONE_2 as libc::c_int - } - _ => state = STATE_ZONE_CONT as libc::c_int, - }, - 1 => { - match *message.offset(cur_token.wrapping_add(1i32 as libc::size_t) as isize) - as libc::c_int - { - 83 => state = STATE_ZONE_3 as libc::c_int, - 68 => { - zone += 1; - state = STATE_ZONE_3 as libc::c_int - } - _ => state = STATE_ZONE_ERR as libc::c_int, - } - } - 2 => { - if *message.offset(cur_token.wrapping_add(2i32 as libc::size_t) as isize) - as libc::c_int - == 'T' as i32 - { - zone *= 100i32; - state = STATE_ZONE_OK as libc::c_int - } else { - state = STATE_ZONE_ERR as libc::c_int - } - } - _ => {} - } - } - match state { - 3 => { - *result = zone; - *indx = cur_token.wrapping_add(3i32 as libc::size_t); - return MAILIMF_NO_ERROR as libc::c_int; - } - 4 => return MAILIMF_ERROR_PARSE as libc::c_int, - _ => {} - } - } - sign = 1i32; - r = mailimf_plus_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - sign = 1i32 - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_minus_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - sign = -1i32 - } - } - if !(r == MAILIMF_NO_ERROR as libc::c_int) { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - sign = 1i32 - } else { - return r; - } - } - r = mailimf_number_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - zone = value.wrapping_mul(sign as libc::c_uint) as libc::c_int; - *indx = cur_token; - *result = zone; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailimf_number_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut uint32_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut digit: libc::c_int = 0; - let mut number: uint32_t = 0; - let mut parsed: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - parsed = 0i32; - number = 0i32 as uint32_t; - loop { - r = mailimf_digit_parse(message, length, &mut cur_token, &mut digit); - if r != MAILIMF_NO_ERROR as libc::c_int { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - break; - } - return r; - } else { - number = (number as libc::c_uint).wrapping_mul(10i32 as libc::c_uint) as uint32_t - as uint32_t; - number = (number as libc::c_uint).wrapping_add(digit as libc::c_uint) as uint32_t - as uint32_t; - parsed = 1i32 - } - } - if 0 == parsed { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - *result = number; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_digit_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - cur_token = *indx; - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - if 0 != is_digit(*message.offset(cur_token as isize)) { - *result = *message.offset(cur_token as isize) as libc::c_int - '0' as i32; - cur_token = cur_token.wrapping_add(1); - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } else { - return MAILIMF_ERROR_PARSE as libc::c_int; - }; -} -/* *************************************************************** */ -#[inline] -unsafe fn is_digit(mut ch: libc::c_char) -> libc::c_int { - return (ch as libc::c_int >= '0' as i32 && ch as libc::c_int <= '9' as i32) as libc::c_int; -} -unsafe fn mailimf_minus_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_unstrict_char_parse(message, length, indx, '-' as i32 as libc::c_char); -} -unsafe fn mailimf_plus_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_unstrict_char_parse(message, length, indx, '+' as i32 as libc::c_char); -} -unsafe fn mailimf_time_of_day_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut phour: *mut libc::c_int, - mut pmin: *mut libc::c_int, - mut psec: *mut libc::c_int, -) -> libc::c_int { - let mut hour: libc::c_int = 0; - let mut min: libc::c_int = 0; - let mut sec: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_hour_parse(message, length, &mut cur_token, &mut hour); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_minute_parse(message, length, &mut cur_token, &mut min); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_colon_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - r = mailimf_second_parse(message, length, &mut cur_token, &mut sec); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - sec = 0i32 - } else { - return r; - } - *phour = hour; - *pmin = min; - *psec = sec; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_second_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut second: uint32_t = 0; - let mut r: libc::c_int = 0; - r = mailimf_number_parse(message, length, indx, &mut second); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *result = second as libc::c_int; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_minute_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut minute: uint32_t = 0; - let mut r: libc::c_int = 0; - r = mailimf_number_parse(message, length, indx, &mut minute); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *result = minute as libc::c_int; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_hour_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut hour: uint32_t = 0; - let mut r: libc::c_int = 0; - r = mailimf_number_parse(message, length, indx, &mut hour); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *result = hour as libc::c_int; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_broken_date_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut pday: *mut libc::c_int, - mut pmonth: *mut libc::c_int, - mut pyear: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut day: libc::c_int = 0; - let mut month: libc::c_int = 0; - let mut year: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - month = 1i32; - r = mailimf_month_parse(message, length, &mut cur_token, &mut month); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - day = 1i32; - r = mailimf_day_parse(message, length, &mut cur_token, &mut day); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - year = 2001i32; - r = mailimf_year_parse(message, length, &mut cur_token, &mut year); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *pday = day; - *pmonth = month; - *pyear = year; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_year_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut number: uint32_t = 0; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_number_parse(message, length, &mut cur_token, &mut number); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - *result = number as libc::c_int; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_day_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut day: uint32_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_number_parse(message, length, &mut cur_token, &mut day); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *result = day as libc::c_int; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_month_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut month: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_month_name_parse(message, length, &mut cur_token, &mut month); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *result = month; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_month_name_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut month: libc::c_int = 0; - let mut guessed_month: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - guessed_month = guess_month(message, length, cur_token); - if guessed_month == -1i32 { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - month_names[(guessed_month - 1i32) as usize].str_0, - strlen(month_names[(guessed_month - 1i32) as usize].str_0), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - month = guessed_month; - *result = month; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -/* -month-name = "Jan" / "Feb" / "Mar" / "Apr" / - "May" / "Jun" / "Jul" / "Aug" / - "Sep" / "Oct" / "Nov" / "Dec" -*/ -static mut month_names: [mailimf_token_value; 12] = [ - mailimf_token_value { - value: 1i32, - str_0: b"Jan\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 2i32, - str_0: b"Feb\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 3i32, - str_0: b"Mar\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 4i32, - str_0: b"Apr\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 5i32, - str_0: b"May\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 6i32, - str_0: b"Jun\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 7i32, - str_0: b"Jul\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 8i32, - str_0: b"Aug\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 9i32, - str_0: b"Sep\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 10i32, - str_0: b"Oct\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 11i32, - str_0: b"Nov\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 12i32, - str_0: b"Dec\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, -]; -unsafe fn guess_month( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: size_t, -) -> libc::c_int { - let mut state: libc::c_int = 0; - state = MONTH_START as libc::c_int; - loop { - if indx >= length { - return -1i32; - } - match state { - 0 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 74 => state = MONTH_J as libc::c_int, - 70 => return 2i32, - 77 => state = MONTH_M as libc::c_int, - 65 => state = MONTH_A as libc::c_int, - 83 => return 9i32, - 79 => return 10i32, - 78 => return 11i32, - 68 => return 12i32, - _ => return -1i32, - } - } - 1 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 65 => return 1i32, - 85 => state = MONTH_JU as libc::c_int, - _ => return -1i32, - } - } - 2 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 78 => return 6i32, - 76 => return 7i32, - _ => return -1i32, - } - } - 3 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 65 => state = MONTH_MA as libc::c_int, - _ => return -1i32, - } - } - 4 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 89 => return 5i32, - 82 => return 3i32, - _ => return -1i32, - } - } - 5 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 80 => return 4i32, - 85 => return 8i32, - _ => return -1i32, - } - } - _ => {} - } - indx = indx.wrapping_add(1) - } -} - -unsafe fn mailimf_date_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut pday: *mut libc::c_int, - mut pmonth: *mut libc::c_int, - mut pyear: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut day: libc::c_int = 0; - let mut month: libc::c_int = 0; - let mut year: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - day = 1i32; - r = mailimf_day_parse(message, length, &mut cur_token, &mut day); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - month = 1i32; - r = mailimf_month_parse(message, length, &mut cur_token, &mut month); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - year = 2001i32; - r = mailimf_year_parse(message, length, &mut cur_token, &mut year); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *pday = day; - *pmonth = month; - *pyear = year; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_comma_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_unstrict_char_parse(message, length, indx, ',' as i32 as libc::c_char); -} -unsafe fn mailimf_day_of_week_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut day_of_week: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_day_name_parse(message, length, &mut cur_token, &mut day_of_week); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - *result = day_of_week; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_day_name_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut day_of_week: libc::c_int = 0; - let mut guessed_day: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - guessed_day = guess_day_name(message, length, cur_token); - if guessed_day == -1i32 { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - day_names[(guessed_day - 1i32) as usize].str_0, - strlen(day_names[(guessed_day - 1i32) as usize].str_0), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - day_of_week = guessed_day; - *result = day_of_week; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -static mut day_names: [mailimf_token_value; 7] = [ - mailimf_token_value { - value: 1i32, - str_0: b"Mon\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 2i32, - str_0: b"Tue\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 3i32, - str_0: b"Wed\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 4i32, - str_0: b"Thu\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 5i32, - str_0: b"Fri\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 6i32, - str_0: b"Sat\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, - mailimf_token_value { - value: 7i32, - str_0: b"Sun\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - }, -]; -unsafe fn guess_day_name( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: size_t, -) -> libc::c_int { - let mut state: libc::c_int = 0; - state = DAY_NAME_START as libc::c_int; - loop { - if indx >= length { - return -1i32; - } - match state { - 0 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 77 => return 1i32, - 84 => state = DAY_NAME_T as libc::c_int, - 87 => return 3i32, - 70 => return 5i32, - 83 => state = DAY_NAME_S as libc::c_int, - _ => return -1i32, - } - } - 1 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 85 => return 2i32, - 72 => return 4i32, - _ => return -1i32, - } - } - 2 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 65 => return 6i32, - 85 => return 7i32, - _ => return -1i32, - } - } - _ => {} - } - indx = indx.wrapping_add(1) - } -} -unsafe fn mailimf_return_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_return, -) -> libc::c_int { - let mut path: *mut mailimf_path = 0 as *mut mailimf_path; - let mut return_path: *mut mailimf_return = 0 as *mut mailimf_return; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Return-Path\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Return-Path\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - path = 0 as *mut mailimf_path; - r = mailimf_path_parse(message, length, &mut cur_token, &mut path); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - return_path = mailimf_return_new(path); - if return_path.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = return_path; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_path_free(path); - } - } - } - return res; -} -unsafe fn mailimf_path_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_path, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut addr_spec: *mut libc::c_char = 0 as *mut libc::c_char; - let mut path: *mut mailimf_path = 0 as *mut mailimf_path; - let mut res: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - addr_spec = 0 as *mut libc::c_char; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - r = mailimf_lower_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_addr_spec_parse(message, length, &mut cur_token, &mut addr_spec); - match r { - 0 => { - current_block = 2370887241019905314; - } - 1 => { - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - res = r; - current_block = 14973541214802992465; - } else { - current_block = 2370887241019905314; - } - } - _ => return r, - } - match current_block { - 14973541214802992465 => {} - _ => { - r = mailimf_greater_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - path = mailimf_path_new(addr_spec); - if path.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if addr_spec.is_null() { - mailimf_addr_spec_free(addr_spec); - } - } else { - *indx = cur_token; - *result = path; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - } - } - return res; -} -unsafe fn mailimf_keywords_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_keywords, -) -> libc::c_int { - let mut keywords: *mut mailimf_keywords = 0 as *mut mailimf_keywords; - let mut list: *mut clist = 0 as *mut clist; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Keywords\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Keywords\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_struct_list_parse( - message, - length, - &mut cur_token, - &mut list, - ',' as i32 as libc::c_char, - ::std::mem::transmute::< - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut *mut libc::c_char, - ) -> libc::c_int, - >, - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut libc::c_void, - ) -> libc::c_int, - >, - >(Some(mailimf_phrase_parse)), - ::std::mem::transmute::< - Option ()>, - Option libc::c_int>, - >(Some(mailimf_phrase_free)), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - keywords = mailimf_keywords_new(list); - if keywords.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = keywords; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - clist_foreach( - list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailimf_phrase_free)), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - } - } - return res; -} -unsafe fn mailimf_comments_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_comments, -) -> libc::c_int { - let mut comments: *mut mailimf_comments = 0 as *mut mailimf_comments; - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Comments\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Comments\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstructured_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - comments = mailimf_comments_new(value); - if comments.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = comments; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_unstructured_free(value); - } - } - } - return res; -} -unsafe fn mailimf_subject_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_subject, -) -> libc::c_int { - let mut subject: *mut mailimf_subject = 0 as *mut mailimf_subject; - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Subject\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Subject\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstructured_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - subject = mailimf_subject_new(value); - if subject.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = subject; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_unstructured_free(value); - } - } - } - return res; -} - -/* exported for IMAP */ -pub unsafe fn mailimf_references_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_references, -) -> libc::c_int { - let mut references: *mut mailimf_references = 0 as *mut mailimf_references; - let mut cur_token: size_t = 0; - let mut msg_id_list: *mut clist = 0 as *mut clist; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"References\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"References\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_msg_id_list_parse(message, length, &mut cur_token, &mut msg_id_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - references = mailimf_references_new(msg_id_list); - if references.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = references; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - clist_foreach( - msg_id_list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailimf_msg_id_free)), - 0 as *mut libc::c_void, - ); - clist_free(msg_id_list); - } - } - } - return res; -} - -pub unsafe fn mailimf_msg_id_list_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut clist, -) -> libc::c_int { - return mailimf_struct_multiple_parse( - message, - length, - indx, - result, - ::std::mem::transmute::< - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut *mut libc::c_char, - ) -> libc::c_int, - >, - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut libc::c_void, - ) -> libc::c_int, - >, - >(Some(mailimf_unstrict_msg_id_parse)), - ::std::mem::transmute::< - Option ()>, - Option libc::c_int>, - >(Some(mailimf_msg_id_free)), - ); -} -unsafe fn mailimf_unstrict_msg_id_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut msgid: *mut libc::c_char = 0 as *mut libc::c_char; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_parse_unwanted_msg_id(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_msg_id_parse(message, length, &mut cur_token, &mut msgid); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_parse_unwanted_msg_id(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - free(msgid as *mut libc::c_void); - return r; - } - *result = msgid; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_parse_unwanted_msg_id( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut word: *mut libc::c_char = 0 as *mut libc::c_char; - let mut token_parsed: libc::c_int = 0; - cur_token = *indx; - token_parsed = 1i32; - while 0 != token_parsed { - token_parsed = 0i32; - r = mailimf_word_parse(message, length, &mut cur_token, &mut word); - if r == MAILIMF_NO_ERROR as libc::c_int { - mailimf_word_free(word); - token_parsed = 1i32 - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - } else { - return r; - } - r = mailimf_semi_colon_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - token_parsed = 1i32 - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - } else { - return r; - } - r = mailimf_comma_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - token_parsed = 1i32 - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - } else { - return r; - } - r = mailimf_plus_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - token_parsed = 1i32 - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - } else { - return r; - } - r = mailimf_colon_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - token_parsed = 1i32 - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - } else { - return r; - } - r = mailimf_point_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - token_parsed = 1i32 - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - } else { - return r; - } - r = mailimf_at_sign_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - token_parsed = 1i32 - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - } else { - return r; - } - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_at_sign_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_unstrict_char_parse(message, length, indx, '@' as i32 as libc::c_char); -} -unsafe fn mailimf_point_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - return mailimf_unstrict_char_parse(message, length, indx, '.' as i32 as libc::c_char); -} - -pub unsafe fn mailimf_word_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut word: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_atom_parse(message, length, &mut cur_token, &mut word); - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_quoted_string_parse(message, length, &mut cur_token, &mut word) - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *result = word; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailimf_quoted_string_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut gstr: *mut MMAPString = 0 as *mut MMAPString; - let mut ch: libc::c_char = 0; - let mut str: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - r = mailimf_dquote_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - gstr = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char); - if gstr.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - loop { - r = mailimf_fws_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - if mmap_string_append_c(gstr, ' ' as i32 as libc::c_char).is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14861901777624095282; - break; - } - } else if r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r; - current_block = 14861901777624095282; - break; - } - r = mailimf_qcontent_parse(message, length, &mut cur_token, &mut ch); - if r == MAILIMF_NO_ERROR as libc::c_int { - if !mmap_string_append_c(gstr, ch).is_null() { - continue; - } - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14861901777624095282; - break; - } else { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 5494826135382683477; - break; - } - res = r; - current_block = 14861901777624095282; - break; - } - } - match current_block { - 5494826135382683477 => { - r = mailimf_dquote_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - str = strdup((*gstr).str_0); - if str.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - mmap_string_free(gstr); - *indx = cur_token; - *result = str; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - _ => {} - } - mmap_string_free(gstr); - } - } - } - return res; -} - -pub unsafe fn mailimf_atom_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut atom: *mut libc::c_char = 0 as *mut libc::c_char; - let mut end: size_t = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - end = cur_token; - if end >= length { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - while 0 != is_atext(*message.offset(end as isize)) { - end = end.wrapping_add(1); - if end >= length { - break; - } - } - if end == cur_token { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - atom = malloc( - end.wrapping_sub(cur_token) - .wrapping_add(1i32 as libc::size_t), - ) as *mut libc::c_char; - if atom.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - strncpy( - atom, - message.offset(cur_token as isize), - end.wrapping_sub(cur_token), - ); - *atom.offset(end.wrapping_sub(cur_token) as isize) = - '\u{0}' as i32 as libc::c_char; - cur_token = end; - *indx = cur_token; - *result = atom; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - return res; -} -unsafe fn mailimf_struct_multiple_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut clist, - mut parser: Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut libc::c_void, - ) -> libc::c_int, - >, - mut destructor: Option libc::c_int>, -) -> libc::c_int { - let mut current_block: u64; - let mut struct_list: *mut clist = 0 as *mut clist; - let mut cur_token: size_t = 0; - let mut value: *mut libc::c_void = 0 as *mut libc::c_void; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = parser.expect("non-null function pointer")( - message, - length, - &mut cur_token, - &mut value as *mut *mut libc::c_void as *mut libc::c_void, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - struct_list = clist_new(); - if struct_list.is_null() { - destructor.expect("non-null function pointer")(value); - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - r = clist_insert_after(struct_list, (*struct_list).last, value); - if r < 0i32 { - destructor.expect("non-null function pointer")(value); - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - loop { - r = parser.expect("non-null function pointer")( - message, - length, - &mut cur_token, - &mut value as *mut *mut libc::c_void as *mut libc::c_void, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 11057878835866523405; - break; - } - res = r; - current_block = 8222683242185098763; - break; - } else { - r = clist_insert_after(struct_list, (*struct_list).last, value); - if !(r < 0i32) { - continue; - } - destructor.expect("non-null function pointer")(value); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 8222683242185098763; - break; - } - } - match current_block { - 8222683242185098763 => {} - _ => { - *result = struct_list; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - clist_foreach( - struct_list, - ::std::mem::transmute::< - Option libc::c_int>, - clist_func, - >(destructor), - 0 as *mut libc::c_void, - ); - clist_free(struct_list); - } - } - return res; -} -unsafe fn mailimf_in_reply_to_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_in_reply_to, -) -> libc::c_int { - let mut in_reply_to: *mut mailimf_in_reply_to = 0 as *mut mailimf_in_reply_to; - let mut cur_token: size_t = 0; - let mut msg_id_list: *mut clist = 0 as *mut clist; - let mut res: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"In-Reply-To\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"In-Reply-To\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_msg_id_list_parse(message, length, &mut cur_token, &mut msg_id_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - in_reply_to = mailimf_in_reply_to_new(msg_id_list); - if in_reply_to.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = in_reply_to; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - clist_foreach( - msg_id_list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailimf_msg_id_free)), - 0 as *mut libc::c_void, - ); - clist_free(msg_id_list); - } - } - } - return res; -} -unsafe fn mailimf_message_id_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_message_id, -) -> libc::c_int { - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut cur_token: size_t = 0; - let mut message_id: *mut mailimf_message_id = 0 as *mut mailimf_message_id; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Message-ID\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Message-ID\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_msg_id_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - message_id = mailimf_message_id_new(value); - if message_id.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = message_id; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_msg_id_free(value); - } - } - } - return res; -} -unsafe fn mailimf_bcc_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_bcc, -) -> libc::c_int { - let mut current_block: u64; - let mut addr_list: *mut mailimf_address_list = 0 as *mut mailimf_address_list; - let mut bcc: *mut mailimf_bcc = 0 as *mut mailimf_bcc; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - addr_list = 0 as *mut mailimf_address_list; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Bcc\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Bcc\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_address_list_parse(message, length, &mut cur_token, &mut addr_list); - match r { - 0 => { - /* do nothing */ - current_block = 2838571290723028321; - } - 1 => { - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - res = r; - current_block = 15260376711225273221; - } else { - current_block = 2838571290723028321; - } - } - _ => { - res = r; - current_block = 15260376711225273221; - } - } - match current_block { - 15260376711225273221 => {} - _ => { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - bcc = mailimf_bcc_new(addr_list); - if bcc.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = bcc; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - } - } - if !addr_list.is_null() { - mailimf_address_list_free(addr_list); - } - return res; -} -unsafe fn mailimf_cc_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_cc, -) -> libc::c_int { - let mut addr_list: *mut mailimf_address_list = 0 as *mut mailimf_address_list; - let mut cc: *mut mailimf_cc = 0 as *mut mailimf_cc; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Cc\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Cc\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_address_list_parse(message, length, &mut cur_token, &mut addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - cc = mailimf_cc_new(addr_list); - if cc.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = cc; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_address_list_free(addr_list); - } - } - } - return res; -} -unsafe fn mailimf_to_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_to, -) -> libc::c_int { - let mut addr_list: *mut mailimf_address_list = 0 as *mut mailimf_address_list; - let mut to: *mut mailimf_to = 0 as *mut mailimf_to; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"To\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"To\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_address_list_parse(message, length, &mut cur_token, &mut addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - to = mailimf_to_new(addr_list); - if to.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = to; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_address_list_free(addr_list); - } - } - } - return res; -} -unsafe fn mailimf_reply_to_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_reply_to, -) -> libc::c_int { - let mut addr_list: *mut mailimf_address_list = 0 as *mut mailimf_address_list; - let mut reply_to: *mut mailimf_reply_to = 0 as *mut mailimf_reply_to; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Reply-To\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Reply-To\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_address_list_parse(message, length, &mut cur_token, &mut addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - reply_to = mailimf_reply_to_new(addr_list); - if reply_to.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = reply_to; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_address_list_free(addr_list); - } - } - } - return res; -} -unsafe fn mailimf_sender_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_sender, -) -> libc::c_int { - let mut mb: *mut mailimf_mailbox = 0 as *mut mailimf_mailbox; - let mut sender: *mut mailimf_sender = 0 as *mut mailimf_sender; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Sender\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Sender\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_mailbox_parse(message, length, &mut cur_token, &mut mb); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - sender = mailimf_sender_new(mb); - if sender.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = sender; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_mailbox_free(mb); - } - } - } - return res; -} -unsafe fn mailimf_from_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_from, -) -> libc::c_int { - let mut mb_list: *mut mailimf_mailbox_list = 0 as *mut mailimf_mailbox_list; - let mut from: *mut mailimf_from = 0 as *mut mailimf_from; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"From\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"From\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_colon_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_mailbox_list_parse(message, length, &mut cur_token, &mut mb_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - from = mailimf_from_new(mb_list); - if from.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = from; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - mailimf_mailbox_list_free(mb_list); - } - } - } - return res; -} -unsafe fn mailimf_orig_date_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_orig_date, -) -> libc::c_int { - let mut date_time: *mut mailimf_date_time = 0 as *mut mailimf_date_time; - let mut orig_date: *mut mailimf_orig_date = 0 as *mut mailimf_orig_date; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"Date:\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"Date:\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_date_time_parse(message, length, &mut cur_token, &mut date_time); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_ignore_unstructured_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - orig_date = mailimf_orig_date_new(date_time); - if orig_date.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = orig_date; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - mailimf_date_time_free(date_time); - } - } - return res; -} -unsafe fn mailimf_ignore_unstructured_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut state: libc::c_int = 0; - let mut terminal: size_t = 0; - cur_token = *indx; - state = UNSTRUCTURED_START as libc::c_int; - terminal = cur_token; - while state != UNSTRUCTURED_OUT as libc::c_int { - match state { - 0 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - terminal = cur_token; - match *message.offset(cur_token as isize) as libc::c_int { - 13 => state = UNSTRUCTURED_CR as libc::c_int, - 10 => state = UNSTRUCTURED_LF as libc::c_int, - _ => state = UNSTRUCTURED_START as libc::c_int, - } - } - 1 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match *message.offset(cur_token as isize) as libc::c_int { - 10 => state = UNSTRUCTURED_LF as libc::c_int, - _ => state = UNSTRUCTURED_START as libc::c_int, - } - } - 2 => { - if cur_token >= length { - state = UNSTRUCTURED_OUT as libc::c_int - } else { - match *message.offset(cur_token as isize) as libc::c_int { - 9 | 32 => state = UNSTRUCTURED_WSP as libc::c_int, - _ => state = UNSTRUCTURED_OUT as libc::c_int, - } - } - } - 3 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match *message.offset(cur_token as isize) as libc::c_int { - 13 => state = UNSTRUCTURED_CR as libc::c_int, - 10 => state = UNSTRUCTURED_LF as libc::c_int, - _ => state = UNSTRUCTURED_START as libc::c_int, - } - } - _ => {} - } - cur_token = cur_token.wrapping_add(1) - } - *indx = terminal; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn guess_header_type( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: size_t, -) -> libc::c_int { - let mut state: libc::c_int = 0; - let mut r: libc::c_int = 0; - state = HEADER_START as libc::c_int; - loop { - if indx >= length { - return MAILIMF_FIELD_NONE as libc::c_int; - } - match state { - 0 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 66 => return MAILIMF_FIELD_BCC as libc::c_int, - 67 => state = HEADER_C as libc::c_int, - 68 => return MAILIMF_FIELD_ORIG_DATE as libc::c_int, - 70 => return MAILIMF_FIELD_FROM as libc::c_int, - 73 => return MAILIMF_FIELD_IN_REPLY_TO as libc::c_int, - 75 => return MAILIMF_FIELD_KEYWORDS as libc::c_int, - 77 => return MAILIMF_FIELD_MESSAGE_ID as libc::c_int, - 82 => state = HEADER_R as libc::c_int, - 84 => return MAILIMF_FIELD_TO as libc::c_int, - 83 => state = HEADER_S as libc::c_int, - _ => return MAILIMF_FIELD_NONE as libc::c_int, - } - } - 1 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 79 => return MAILIMF_FIELD_COMMENTS as libc::c_int, - 67 => return MAILIMF_FIELD_CC as libc::c_int, - _ => return MAILIMF_FIELD_NONE as libc::c_int, - } - } - 2 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 69 => state = HEADER_RE as libc::c_int, - _ => return MAILIMF_FIELD_NONE as libc::c_int, - } - } - 3 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 70 => return MAILIMF_FIELD_REFERENCES as libc::c_int, - 80 => return MAILIMF_FIELD_REPLY_TO as libc::c_int, - 83 => state = HEADER_RES as libc::c_int, - 84 => return MAILIMF_FIELD_RETURN_PATH as libc::c_int, - _ => return MAILIMF_FIELD_NONE as libc::c_int, - } - } - 4 => { - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 69 => return MAILIMF_FIELD_SENDER as libc::c_int, - 85 => return MAILIMF_FIELD_SUBJECT as libc::c_int, - _ => return MAILIMF_FIELD_NONE as libc::c_int, - } - } - 5 => { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut indx, - b"ent-\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"ent-\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return MAILIMF_FIELD_NONE as libc::c_int; - } - if indx >= length { - return MAILIMF_FIELD_NONE as libc::c_int; - } - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 68 => return MAILIMF_FIELD_RESENT_DATE as libc::c_int, - 70 => return MAILIMF_FIELD_RESENT_FROM as libc::c_int, - 83 => return MAILIMF_FIELD_RESENT_SENDER as libc::c_int, - 84 => return MAILIMF_FIELD_RESENT_TO as libc::c_int, - 67 => return MAILIMF_FIELD_RESENT_CC as libc::c_int, - 66 => return MAILIMF_FIELD_RESENT_BCC as libc::c_int, - 77 => return MAILIMF_FIELD_RESENT_MSG_ID as libc::c_int, - _ => return MAILIMF_FIELD_NONE as libc::c_int, - } - } - _ => {} - } - indx = indx.wrapping_add(1) - } -} -/* - mailimf_envelope_fields_parse will parse the given fields (Date, - From, Sender, Reply-To, To, Cc, Bcc, Message-ID, In-Reply-To, - References and Subject) - - @param message this is a string containing the header fields - @param length this is the size of the given string - @param indx this is a pointer to the start of the header fields in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ - -pub unsafe fn mailimf_envelope_fields_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_fields, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut list: *mut clist = 0 as *mut clist; - let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - loop { - let mut elt: *mut mailimf_field = 0 as *mut mailimf_field; - r = mailimf_envelope_field_parse(message, length, &mut cur_token, &mut elt); - if r == MAILIMF_NO_ERROR as libc::c_int { - r = clist_insert_after(list, (*list).last, elt as *mut libc::c_void); - if !(r < 0i32) { - continue; - } - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 894413572976700158; - break; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_ignore_field_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - continue; - } - /* do nothing */ - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 2719512138335094285; - break; - } - res = r; - current_block = 894413572976700158; - break; - } else { - res = r; - current_block = 894413572976700158; - break; - } - } - match current_block { - 2719512138335094285 => { - fields = mailimf_fields_new(list); - if fields.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = fields; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - _ => {} - } - if !list.is_null() { - clist_foreach( - list, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailimf_field_free), - ), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - } - return res; -} -/* - mailimf_ignore_field_parse will skip the given field - - @param message this is a string containing the header field - @param length this is the size of the given string - @param indx this is a pointer to the start of the header field in - the given string, (* indx) is modified to point at the end - of the parsed data - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_ignore_field_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut has_field: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut state: libc::c_int = 0; - let mut terminal: size_t = 0; - has_field = 0i32; - cur_token = *indx; - terminal = cur_token; - state = UNSTRUCTURED_START as libc::c_int; - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match *message.offset(cur_token as isize) as libc::c_int { - 13 => return MAILIMF_ERROR_PARSE as libc::c_int, - 10 => return MAILIMF_ERROR_PARSE as libc::c_int, - _ => {} - } - while state != UNSTRUCTURED_OUT as libc::c_int { - match state { - 0 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match *message.offset(cur_token as isize) as libc::c_int { - 13 => state = UNSTRUCTURED_CR as libc::c_int, - 10 => state = UNSTRUCTURED_LF as libc::c_int, - 58 => { - has_field = 1i32; - state = UNSTRUCTURED_START as libc::c_int - } - _ => state = UNSTRUCTURED_START as libc::c_int, - } - } - 1 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match *message.offset(cur_token as isize) as libc::c_int { - 10 => state = UNSTRUCTURED_LF as libc::c_int, - 58 => { - has_field = 1i32; - state = UNSTRUCTURED_START as libc::c_int - } - _ => state = UNSTRUCTURED_START as libc::c_int, - } - } - 2 => { - if cur_token >= length { - terminal = cur_token; - state = UNSTRUCTURED_OUT as libc::c_int - } else { - match *message.offset(cur_token as isize) as libc::c_int { - 9 | 32 => state = UNSTRUCTURED_WSP as libc::c_int, - _ => { - terminal = cur_token; - state = UNSTRUCTURED_OUT as libc::c_int - } - } - } - } - 3 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match *message.offset(cur_token as isize) as libc::c_int { - 13 => state = UNSTRUCTURED_CR as libc::c_int, - 10 => state = UNSTRUCTURED_LF as libc::c_int, - 58 => { - has_field = 1i32; - state = UNSTRUCTURED_START as libc::c_int - } - _ => state = UNSTRUCTURED_START as libc::c_int, - } - } - _ => {} - } - cur_token = cur_token.wrapping_add(1) - } - if 0 == has_field { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - *indx = terminal; - return MAILIMF_NO_ERROR as libc::c_int; -} -/* -static int mailimf_ftext_parse(const char * message, size_t length, - size_t * indx, gchar * result) -{ - return mailimf_typed_text_parse(message, length, indx, result, is_ftext); -} -*/ -unsafe fn mailimf_envelope_field_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_field, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut type_0: libc::c_int = 0; - let mut orig_date: *mut mailimf_orig_date = 0 as *mut mailimf_orig_date; - let mut from: *mut mailimf_from = 0 as *mut mailimf_from; - let mut sender: *mut mailimf_sender = 0 as *mut mailimf_sender; - let mut reply_to: *mut mailimf_reply_to = 0 as *mut mailimf_reply_to; - let mut to: *mut mailimf_to = 0 as *mut mailimf_to; - let mut cc: *mut mailimf_cc = 0 as *mut mailimf_cc; - let mut bcc: *mut mailimf_bcc = 0 as *mut mailimf_bcc; - let mut message_id: *mut mailimf_message_id = 0 as *mut mailimf_message_id; - let mut in_reply_to: *mut mailimf_in_reply_to = 0 as *mut mailimf_in_reply_to; - let mut references: *mut mailimf_references = 0 as *mut mailimf_references; - let mut subject: *mut mailimf_subject = 0 as *mut mailimf_subject; - let mut optional_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field; - let mut field: *mut mailimf_field = 0 as *mut mailimf_field; - let mut guessed_type: libc::c_int = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - orig_date = 0 as *mut mailimf_orig_date; - from = 0 as *mut mailimf_from; - sender = 0 as *mut mailimf_sender; - reply_to = 0 as *mut mailimf_reply_to; - to = 0 as *mut mailimf_to; - cc = 0 as *mut mailimf_cc; - bcc = 0 as *mut mailimf_bcc; - message_id = 0 as *mut mailimf_message_id; - in_reply_to = 0 as *mut mailimf_in_reply_to; - references = 0 as *mut mailimf_references; - subject = 0 as *mut mailimf_subject; - optional_field = 0 as *mut mailimf_optional_field; - guessed_type = guess_header_type(message, length, cur_token); - type_0 = MAILIMF_FIELD_NONE as libc::c_int; - match guessed_type { - 9 => { - r = mailimf_orig_date_parse(message, length, &mut cur_token, &mut orig_date); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - 10 => { - r = mailimf_from_parse(message, length, &mut cur_token, &mut from); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - 11 => { - r = mailimf_sender_parse(message, length, &mut cur_token, &mut sender); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - 12 => { - r = mailimf_reply_to_parse(message, length, &mut cur_token, &mut reply_to); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - 13 => { - r = mailimf_to_parse(message, length, &mut cur_token, &mut to); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - 14 => { - r = mailimf_cc_parse(message, length, &mut cur_token, &mut cc); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - 15 => { - r = mailimf_bcc_parse(message, length, &mut cur_token, &mut bcc); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - 16 => { - r = mailimf_message_id_parse(message, length, &mut cur_token, &mut message_id); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - 17 => { - r = mailimf_in_reply_to_parse(message, length, &mut cur_token, &mut in_reply_to); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - 18 => { - r = mailimf_references_parse(message, length, &mut cur_token, &mut references); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - 19 => { - r = mailimf_subject_parse(message, length, &mut cur_token, &mut subject); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 4488496028633655612; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 4488496028633655612; - } else { - /* do nothing */ - res = r; - current_block = 15605017197726313499; - } - } - _ => { - current_block = 4488496028633655612; - } - } - match current_block { - 4488496028633655612 => { - if type_0 == MAILIMF_FIELD_NONE as libc::c_int { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - field = mailimf_field_new( - type_0, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - orig_date, - from, - sender, - reply_to, - to, - cc, - bcc, - message_id, - in_reply_to, - references, - subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - optional_field, - ); - if field.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !orig_date.is_null() { - mailimf_orig_date_free(orig_date); - } - if !from.is_null() { - mailimf_from_free(from); - } - if !sender.is_null() { - mailimf_sender_free(sender); - } - if !reply_to.is_null() { - mailimf_reply_to_free(reply_to); - } - if !to.is_null() { - mailimf_to_free(to); - } - if !cc.is_null() { - mailimf_cc_free(cc); - } - if !bcc.is_null() { - mailimf_bcc_free(bcc); - } - if !message_id.is_null() { - mailimf_message_id_free(message_id); - } - if !in_reply_to.is_null() { - mailimf_in_reply_to_free(in_reply_to); - } - if !references.is_null() { - mailimf_references_free(references); - } - if !subject.is_null() { - mailimf_subject_free(subject); - } - if !optional_field.is_null() { - mailimf_optional_field_free(optional_field); - } - } else { - *result = field; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - _ => {} - } - return res; -} -/* - mailimf_envelope_fields will parse the given fields (Date, - From, Sender, Reply-To, To, Cc, Bcc, Message-ID, In-Reply-To, - References and Subject), other fields will be added as optional - fields. - - @param message this is a string containing the header fields - @param length this is the size of the given string - @param indx this is a pointer to the start of the header fields in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_envelope_and_optional_fields_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_fields, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut list: *mut clist = 0 as *mut clist; - let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - list = 0 as *mut clist; - r = mailimf_struct_multiple_parse( - message, - length, - &mut cur_token, - &mut list, - ::std::mem::transmute::< - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut *mut mailimf_field, - ) -> libc::c_int, - >, - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut libc::c_void, - ) -> libc::c_int, - >, - >(Some(mailimf_envelope_or_optional_field_parse)), - ::std::mem::transmute::< - Option ()>, - Option libc::c_int>, - >(Some(mailimf_field_free)), - ); - match r { - 0 => { - /* do nothing */ - current_block = 11050875288958768710; - } - 1 => { - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 7755940856643933760; - } else { - current_block = 11050875288958768710; - } - } - _ => { - res = r; - current_block = 7755940856643933760; - } - } - match current_block { - 11050875288958768710 => { - fields = mailimf_fields_new(list); - if fields.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !list.is_null() { - clist_foreach( - list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailimf_field_free)), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - } else { - *result = fields; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - _ => {} - } - return res; -} -unsafe fn mailimf_envelope_or_optional_field_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_field, -) -> libc::c_int { - let mut r: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut optional_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field; - let mut field: *mut mailimf_field = 0 as *mut mailimf_field; - r = mailimf_envelope_field_parse(message, length, indx, result); - if r == MAILIMF_NO_ERROR as libc::c_int { - return MAILIMF_NO_ERROR as libc::c_int; - } - cur_token = *indx; - r = mailimf_optional_field_parse(message, length, &mut cur_token, &mut optional_field); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - field = mailimf_field_new( - MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_reply_to, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_in_reply_to, - 0 as *mut mailimf_references, - 0 as *mut mailimf_subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - optional_field, - ); - if field.is_null() { - mailimf_optional_field_free(optional_field); - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - *result = field; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} - -/* - mailimf_envelope_fields will parse the given fields as optional - fields. - - @param message this is a string containing the header fields - @param length this is the size of the given string - @param indx this is a pointer to the start of the header fields in - the given string, (* indx) is modified to point at the end - of the parsed data - @param result the result of the parse operation is stored in - (* result) - - @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error -*/ -pub unsafe fn mailimf_optional_fields_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_fields, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut list: *mut clist = 0 as *mut clist; - let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - list = 0 as *mut clist; - r = mailimf_struct_multiple_parse( - message, - length, - &mut cur_token, - &mut list, - ::std::mem::transmute::< - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut *mut mailimf_field, - ) -> libc::c_int, - >, - Option< - unsafe fn( - _: *const libc::c_char, - _: size_t, - _: *mut size_t, - _: *mut libc::c_void, - ) -> libc::c_int, - >, - >(Some(mailimf_only_optional_field_parse)), - ::std::mem::transmute::< - Option ()>, - Option libc::c_int>, - >(Some(mailimf_field_free)), - ); - match r { - 0 => { - /* do nothing */ - current_block = 11050875288958768710; - } - 1 => { - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 4409055091581443388; - } else { - current_block = 11050875288958768710; - } - } - _ => { - res = r; - current_block = 4409055091581443388; - } - } - match current_block { - 11050875288958768710 => { - fields = mailimf_fields_new(list); - if fields.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !list.is_null() { - clist_foreach( - list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailimf_field_free)), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - } else { - *result = fields; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - _ => {} - } - return res; -} -unsafe fn mailimf_only_optional_field_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailimf_field, -) -> libc::c_int { - let mut r: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut optional_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field; - let mut field: *mut mailimf_field = 0 as *mut mailimf_field; - cur_token = *indx; - r = mailimf_optional_field_parse(message, length, &mut cur_token, &mut optional_field); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - field = mailimf_field_new( - MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_reply_to, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_in_reply_to, - 0 as *mut mailimf_references, - 0 as *mut mailimf_subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - optional_field, - ); - if field.is_null() { - mailimf_optional_field_free(optional_field); - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - *result = field; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailimf_custom_string_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, - mut is_custom_char: Option libc::c_int>, -) -> libc::c_int { - let mut begin: size_t = 0; - let mut end: size_t = 0; - let mut gstr: *mut libc::c_char = 0 as *mut libc::c_char; - begin = *indx; - end = begin; - if end >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - while 0 != is_custom_char.expect("non-null function pointer")(*message.offset(end as isize)) { - end = end.wrapping_add(1); - if end >= length { - break; - } - } - if end != begin { - gstr = - malloc(end.wrapping_sub(begin).wrapping_add(1i32 as libc::size_t)) as *mut libc::c_char; - if gstr.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - strncpy( - gstr, - message.offset(begin as isize), - end.wrapping_sub(begin), - ); - *gstr.offset(end.wrapping_sub(begin) as isize) = '\u{0}' as i32 as libc::c_char; - *indx = end; - *result = gstr; - return MAILIMF_NO_ERROR as libc::c_int; - } else { - return MAILIMF_ERROR_PARSE as libc::c_int; - }; -} diff --git a/mmime/src/mailimf/types.rs b/mmime/src/mailimf/types.rs deleted file mode 100644 index b5e38cd80..000000000 --- a/mmime/src/mailimf/types.rs +++ /dev/null @@ -1,1196 +0,0 @@ -use libc; - -use crate::clist::*; -use crate::other::*; - -/* - IMPORTANT NOTE: - - All allocation functions will take as argument allocated data - and will store these data in the structure they will allocate. - Data should be persistant during all the use of the structure - and will be freed by the free function of the structure - - allocation functions will return NULL on failure -*/ -/* - mailimf_date_time is a date - - - day is the day of month (1 to 31) - - - month (1 to 12) - - - year (4 digits) - - - hour (0 to 23) - - - min (0 to 59) - - - sec (0 to 59) - - - zone (this is the decimal value that we can read, for example: - for "-0200", the value is -200) -*/ -#[derive(Copy, Clone, Debug)] -#[repr(C)] -pub struct mailimf_date_time { - pub dt_day: libc::c_int, - pub dt_month: libc::c_int, - pub dt_year: libc::c_int, - pub dt_hour: libc::c_int, - pub dt_min: libc::c_int, - pub dt_sec: libc::c_int, - pub dt_zone: libc::c_int, -} -/* this is the type of address */ -/* if this is a group -(group_name: address1@domain1, - address2@domain2; ) */ -pub const MAILIMF_ADDRESS_GROUP: libc::c_uint = 2; -/* if this is a mailbox (mailbox@domain) */ -pub const MAILIMF_ADDRESS_MAILBOX: libc::c_uint = 1; -/* on parse error */ -pub const MAILIMF_ADDRESS_ERROR: libc::c_uint = 0; -/* - mailimf_address is an address - - - type can be MAILIMF_ADDRESS_MAILBOX or MAILIMF_ADDRESS_GROUP - - - mailbox is a mailbox if type is MAILIMF_ADDRESS_MAILBOX - - - group is a group if type is MAILIMF_ADDRESS_GROUP -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_address { - pub ad_type: libc::c_int, - pub ad_data: unnamed_0, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub union unnamed_0 { - pub ad_mailbox: *mut mailimf_mailbox, - pub ad_group: *mut mailimf_group, -} -/* - mailimf_group is a group - - - display_name is the name that will be displayed for this group, - for example 'group_name' in - 'group_name: address1@domain1, address2@domain2;', should be allocated - with malloc() - - - mb_list is a list of mailboxes -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_group { - pub grp_display_name: *mut libc::c_char, - pub grp_mb_list: *mut mailimf_mailbox_list, -} -/* - mailimf_mailbox_list is a list of mailboxes - - - list is a list of mailboxes -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_mailbox_list { - pub mb_list: *mut clist, -} -/* - mailimf_mailbox is a mailbox - - - display_name is the name that will be displayed for this mailbox, - for example 'name' in '"name" , - should be allocated with malloc() - - - addr_spec is the mailbox, for example 'mailbox@domain' - in '"name" , should be allocated with malloc() -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_mailbox { - pub mb_display_name: *mut libc::c_char, - pub mb_addr_spec: *mut libc::c_char, -} -/* - mailimf_address_list is a list of addresses - - - list is a list of addresses -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_address_list { - pub ad_list: *mut clist, -} -/* - mailimf_body is the text part of a message - - - text is the beginning of the text part, it is a substring - of an other string - - - size is the size of the text part -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_body { - pub bd_text: *const libc::c_char, - pub bd_size: size_t, -} -/* - mailimf_message is the content of the message - - - msg_fields is the header fields of the message - - - msg_body is the text part of the message -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_message { - pub msg_fields: *mut mailimf_fields, - pub msg_body: *mut mailimf_body, -} -/* - mailimf_fields is a list of header fields - - - fld_list is a list of header fields -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_fields { - pub fld_list: *mut clist, -} -/* - mailimf_field is a field - - - fld_type is the type of the field - - - fld_data.fld_return_path is the parsed content of the Return-Path - field if type is MAILIMF_FIELD_RETURN_PATH - - - fld_data.fld_resent_date is the parsed content of the Resent-Date field - if type is MAILIMF_FIELD_RESENT_DATE - - - fld_data.fld_resent_from is the parsed content of the Resent-From field - - - fld_data.fld_resent_sender is the parsed content of the Resent-Sender field - - - fld_data.fld_resent_to is the parsed content of the Resent-To field - - - fld_data.fld_resent_cc is the parsed content of the Resent-Cc field - - - fld_data.fld_resent_bcc is the parsed content of the Resent-Bcc field - - - fld_data.fld_resent_msg_id is the parsed content of the Resent-Message-ID - field - - - fld_data.fld_orig_date is the parsed content of the Date field - - - fld_data.fld_from is the parsed content of the From field - - - fld_data.fld_sender is the parsed content of the Sender field - - - fld_data.fld_reply_to is the parsed content of the Reply-To field - - - fld_data.fld_to is the parsed content of the To field - - - fld_data.fld_cc is the parsed content of the Cc field - - - fld_data.fld_bcc is the parsed content of the Bcc field - - - fld_data.fld_message_id is the parsed content of the Message-ID field - - - fld_data.fld_in_reply_to is the parsed content of the In-Reply-To field - - - fld_data.fld_references is the parsed content of the References field - - - fld_data.fld_subject is the content of the Subject field - - - fld_data.fld_comments is the content of the Comments field - - - fld_data.fld_keywords is the parsed content of the Keywords field - - - fld_data.fld_optional_field is an other field and is not parsed -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_field { - pub fld_type: libc::c_int, - pub fld_data: unnamed_1, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub union unnamed_1 { - pub fld_return_path: *mut mailimf_return, - pub fld_resent_date: *mut mailimf_orig_date, - pub fld_resent_from: *mut mailimf_from, - pub fld_resent_sender: *mut mailimf_sender, - pub fld_resent_to: *mut mailimf_to, - pub fld_resent_cc: *mut mailimf_cc, - pub fld_resent_bcc: *mut mailimf_bcc, - pub fld_resent_msg_id: *mut mailimf_message_id, - pub fld_orig_date: *mut mailimf_orig_date, - pub fld_from: *mut mailimf_from, - pub fld_sender: *mut mailimf_sender, - pub fld_reply_to: *mut mailimf_reply_to, - pub fld_to: *mut mailimf_to, - pub fld_cc: *mut mailimf_cc, - pub fld_bcc: *mut mailimf_bcc, - pub fld_message_id: *mut mailimf_message_id, - pub fld_in_reply_to: *mut mailimf_in_reply_to, - pub fld_references: *mut mailimf_references, - pub fld_subject: *mut mailimf_subject, - pub fld_comments: *mut mailimf_comments, - pub fld_keywords: *mut mailimf_keywords, - pub fld_optional_field: *mut mailimf_optional_field, -} -/* - mailimf_optional_field is a non-parsed field - - - fld_name is the name of the field - - - fld_value is the value of the field -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_optional_field { - pub fld_name: *mut libc::c_char, - pub fld_value: *mut libc::c_char, -} -/* - mailimf_keywords is the parsed Keywords field - - - kw_list is the list of keywords -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_keywords { - pub kw_list: *mut clist, -} -/* - mailimf_comments is the parsed Comments field - - - cm_value is the value of the field -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_comments { - pub cm_value: *mut libc::c_char, -} -/* - mailimf_subject is the parsed Subject field - - - sbj_value is the value of the field -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_subject { - pub sbj_value: *mut libc::c_char, -} -/* - mailimf_references is the parsed References field - - - msg_id_list is the list of message identifiers -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_references { - pub mid_list: *mut clist, -} -/* - mailimf_in_reply_to is the parsed In-Reply-To field - - - mid_list is the list of message identifers -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_in_reply_to { - pub mid_list: *mut clist, -} -/* - mailimf_message_id is the parsed Message-ID field - - - mid_value is the message identifier -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_message_id { - pub mid_value: *mut libc::c_char, -} -/* - mailimf_bcc is the parsed Bcc field - - - bcc_addr_list is the parsed addres list -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_bcc { - pub bcc_addr_list: *mut mailimf_address_list, -} -/* - mailimf_cc is the parsed Cc field - - - cc_addr_list is the parsed addres list -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_cc { - pub cc_addr_list: *mut mailimf_address_list, -} -/* - mailimf_to is the parsed To field - - - to_addr_list is the parsed address list -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_to { - pub to_addr_list: *mut mailimf_address_list, -} -/* - mailimf_reply_to is the parsed Reply-To field - - - rt_addr_list is the parsed address list -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_reply_to { - pub rt_addr_list: *mut mailimf_address_list, -} -/* - mailimf_sender is the parsed Sender field - - - snd_mb is the parsed mailbox -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_sender { - pub snd_mb: *mut mailimf_mailbox, -} -/* - mailimf_from is the parsed From field - - - mb_list is the parsed mailbox list -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_from { - pub frm_mb_list: *mut mailimf_mailbox_list, -} -/* - mailimf_orig_date is the parsed Date field - - - date_time is the parsed date -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_orig_date { - pub dt_date_time: *mut mailimf_date_time, -} -/* - mailimf_return is the parsed Return-Path field - - - ret_path is the parsed value of Return-Path -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_return { - pub ret_path: *mut mailimf_path, -} -/* - mailimf_path is the parsed value of Return-Path - - - pt_addr_spec is a mailbox -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_path { - pub pt_addr_spec: *mut libc::c_char, -} -/* other field */ -pub const MAILIMF_FIELD_OPTIONAL_FIELD: unnamed_2 = 22; -/* Keywords */ -pub const MAILIMF_FIELD_KEYWORDS: unnamed_2 = 21; -/* Comments */ -pub const MAILIMF_FIELD_COMMENTS: unnamed_2 = 20; -/* Subject */ -pub const MAILIMF_FIELD_SUBJECT: unnamed_2 = 19; -/* References */ -pub const MAILIMF_FIELD_REFERENCES: unnamed_2 = 18; -/* In-Reply-To */ -pub const MAILIMF_FIELD_IN_REPLY_TO: unnamed_2 = 17; -/* Message-ID */ -pub const MAILIMF_FIELD_MESSAGE_ID: unnamed_2 = 16; -/* Bcc */ -pub const MAILIMF_FIELD_BCC: unnamed_2 = 15; -/* Cc */ -pub const MAILIMF_FIELD_CC: unnamed_2 = 14; -/* To */ -pub const MAILIMF_FIELD_TO: unnamed_2 = 13; -/* Reply-To */ -pub const MAILIMF_FIELD_REPLY_TO: unnamed_2 = 12; -/* Sender */ -pub const MAILIMF_FIELD_SENDER: unnamed_2 = 11; -/* From */ -pub const MAILIMF_FIELD_FROM: unnamed_2 = 10; -/* Date */ -pub const MAILIMF_FIELD_ORIG_DATE: unnamed_2 = 9; -/* Resent-Message-ID */ -pub const MAILIMF_FIELD_RESENT_MSG_ID: unnamed_2 = 8; -/* Resent-Bcc */ -pub const MAILIMF_FIELD_RESENT_BCC: unnamed_2 = 7; -/* Resent-Cc */ -pub const MAILIMF_FIELD_RESENT_CC: unnamed_2 = 6; -/* Resent-To */ -pub const MAILIMF_FIELD_RESENT_TO: unnamed_2 = 5; -/* Resent-Sender */ -pub const MAILIMF_FIELD_RESENT_SENDER: unnamed_2 = 4; -/* Resent-From */ -pub const MAILIMF_FIELD_RESENT_FROM: unnamed_2 = 3; -/* Resent-Date */ -pub const MAILIMF_FIELD_RESENT_DATE: unnamed_2 = 2; -/* Return-Path */ -pub const MAILIMF_FIELD_RETURN_PATH: unnamed_2 = 1; -/* this is a type of field */ -pub type unnamed_2 = libc::c_uint; -/* on parse error */ -pub const MAILIMF_FIELD_NONE: unnamed_2 = 0; -#[no_mangle] -pub unsafe fn mailimf_date_time_new( - mut dt_day: libc::c_int, - mut dt_month: libc::c_int, - mut dt_year: libc::c_int, - mut dt_hour: libc::c_int, - mut dt_min: libc::c_int, - mut dt_sec: libc::c_int, - mut dt_zone: libc::c_int, -) -> *mut mailimf_date_time { - let mut date_time: *mut mailimf_date_time = 0 as *mut mailimf_date_time; - date_time = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailimf_date_time; - if date_time.is_null() { - return 0 as *mut mailimf_date_time; - } - (*date_time).dt_day = dt_day; - (*date_time).dt_month = dt_month; - (*date_time).dt_year = dt_year; - (*date_time).dt_hour = dt_hour; - (*date_time).dt_min = dt_min; - (*date_time).dt_sec = dt_sec; - (*date_time).dt_zone = dt_zone; - return date_time; -} -#[no_mangle] -pub unsafe fn mailimf_date_time_free(mut date_time: *mut mailimf_date_time) { - free(date_time as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_address_new( - mut ad_type: libc::c_int, - mut ad_mailbox: *mut mailimf_mailbox, - mut ad_group: *mut mailimf_group, -) -> *mut mailimf_address { - let mut address: *mut mailimf_address = 0 as *mut mailimf_address; - address = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_address; - if address.is_null() { - return 0 as *mut mailimf_address; - } - (*address).ad_type = ad_type; - match ad_type { - 1 => (*address).ad_data.ad_mailbox = ad_mailbox, - 2 => (*address).ad_data.ad_group = ad_group, - _ => {} - } - return address; -} -#[no_mangle] -pub unsafe fn mailimf_address_free(mut address: *mut mailimf_address) { - match (*address).ad_type { - 1 => { - mailimf_mailbox_free((*address).ad_data.ad_mailbox); - } - 2 => { - mailimf_group_free((*address).ad_data.ad_group); - } - _ => {} - } - free(address as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_group_free(mut group: *mut mailimf_group) { - if !(*group).grp_mb_list.is_null() { - mailimf_mailbox_list_free((*group).grp_mb_list); - } - mailimf_display_name_free((*group).grp_display_name); - free(group as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_display_name_free(mut display_name: *mut libc::c_char) { - mailimf_phrase_free(display_name); -} -#[no_mangle] -pub unsafe fn mailimf_phrase_free(mut phrase: *mut libc::c_char) { - free(phrase as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_mailbox_list_free(mut mb_list: *mut mailimf_mailbox_list) { - clist_foreach( - (*mb_list).mb_list, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailimf_mailbox_free), - ), - 0 as *mut libc::c_void, - ); - clist_free((*mb_list).mb_list); - free(mb_list as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_mailbox_free(mut mailbox: *mut mailimf_mailbox) { - if !(*mailbox).mb_display_name.is_null() { - mailimf_display_name_free((*mailbox).mb_display_name); - } - mailimf_addr_spec_free((*mailbox).mb_addr_spec); - free(mailbox as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_addr_spec_free(mut addr_spec: *mut libc::c_char) { - free(addr_spec as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_mailbox_new( - mut mb_display_name: *mut libc::c_char, - mut mb_addr_spec: *mut libc::c_char, -) -> *mut mailimf_mailbox { - let mut mb: *mut mailimf_mailbox = 0 as *mut mailimf_mailbox; - mb = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_mailbox; - if mb.is_null() { - return 0 as *mut mailimf_mailbox; - } - (*mb).mb_display_name = mb_display_name; - (*mb).mb_addr_spec = mb_addr_spec; - return mb; -} -#[no_mangle] -pub unsafe fn mailimf_group_new( - mut grp_display_name: *mut libc::c_char, - mut grp_mb_list: *mut mailimf_mailbox_list, -) -> *mut mailimf_group { - let mut group: *mut mailimf_group = 0 as *mut mailimf_group; - group = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_group; - if group.is_null() { - return 0 as *mut mailimf_group; - } - (*group).grp_display_name = grp_display_name; - (*group).grp_mb_list = grp_mb_list; - return group; -} -#[no_mangle] -pub unsafe fn mailimf_mailbox_list_new(mut mb_list: *mut clist) -> *mut mailimf_mailbox_list { - let mut mbl: *mut mailimf_mailbox_list = 0 as *mut mailimf_mailbox_list; - mbl = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailimf_mailbox_list; - if mbl.is_null() { - return 0 as *mut mailimf_mailbox_list; - } - (*mbl).mb_list = mb_list; - return mbl; -} - -pub unsafe fn mailimf_address_list_new(mut ad_list: *mut clist) -> *mut mailimf_address_list { - let mut addr_list: *mut mailimf_address_list = 0 as *mut mailimf_address_list; - addr_list = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailimf_address_list; - if addr_list.is_null() { - return 0 as *mut mailimf_address_list; - } - (*addr_list).ad_list = ad_list; - return addr_list; -} -#[no_mangle] -pub unsafe fn mailimf_address_list_free(mut addr_list: *mut mailimf_address_list) { - clist_foreach( - (*addr_list).ad_list, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailimf_address_free), - ), - 0 as *mut libc::c_void, - ); - clist_free((*addr_list).ad_list); - free(addr_list as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_body_new( - mut bd_text: *const libc::c_char, - mut bd_size: size_t, -) -> *mut mailimf_body { - let mut body: *mut mailimf_body = 0 as *mut mailimf_body; - body = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_body; - if body.is_null() { - return 0 as *mut mailimf_body; - } - (*body).bd_text = bd_text; - (*body).bd_size = bd_size; - return body; -} -#[no_mangle] -pub unsafe fn mailimf_body_free(mut body: *mut mailimf_body) { - free(body as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_message_new( - mut msg_fields: *mut mailimf_fields, - mut msg_body: *mut mailimf_body, -) -> *mut mailimf_message { - let mut message: *mut mailimf_message = 0 as *mut mailimf_message; - message = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_message; - if message.is_null() { - return 0 as *mut mailimf_message; - } - (*message).msg_fields = msg_fields; - (*message).msg_body = msg_body; - return message; -} -#[no_mangle] -pub unsafe fn mailimf_message_free(mut message: *mut mailimf_message) { - mailimf_body_free((*message).msg_body); - mailimf_fields_free((*message).msg_fields); - free(message as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_fields_free(mut fields: *mut mailimf_fields) { - if !(*fields).fld_list.is_null() { - clist_foreach( - (*fields).fld_list, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailimf_field_free), - ), - 0 as *mut libc::c_void, - ); - clist_free((*fields).fld_list); - } - free(fields as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_field_free(mut field: *mut mailimf_field) { - match (*field).fld_type { - 1 => { - mailimf_return_free((*field).fld_data.fld_return_path); - } - 2 => { - mailimf_orig_date_free((*field).fld_data.fld_resent_date); - } - 3 => { - mailimf_from_free((*field).fld_data.fld_resent_from); - } - 4 => { - mailimf_sender_free((*field).fld_data.fld_resent_sender); - } - 5 => { - mailimf_to_free((*field).fld_data.fld_resent_to); - } - 6 => { - mailimf_cc_free((*field).fld_data.fld_resent_cc); - } - 7 => { - mailimf_bcc_free((*field).fld_data.fld_resent_bcc); - } - 8 => { - mailimf_message_id_free((*field).fld_data.fld_resent_msg_id); - } - 9 => { - mailimf_orig_date_free((*field).fld_data.fld_orig_date); - } - 10 => { - mailimf_from_free((*field).fld_data.fld_from); - } - 11 => { - mailimf_sender_free((*field).fld_data.fld_sender); - } - 12 => { - mailimf_reply_to_free((*field).fld_data.fld_reply_to); - } - 13 => { - mailimf_to_free((*field).fld_data.fld_to); - } - 14 => { - mailimf_cc_free((*field).fld_data.fld_cc); - } - 15 => { - mailimf_bcc_free((*field).fld_data.fld_bcc); - } - 16 => { - mailimf_message_id_free((*field).fld_data.fld_message_id); - } - 17 => { - mailimf_in_reply_to_free((*field).fld_data.fld_in_reply_to); - } - 18 => { - mailimf_references_free((*field).fld_data.fld_references); - } - 19 => { - mailimf_subject_free((*field).fld_data.fld_subject); - } - 20 => { - mailimf_comments_free((*field).fld_data.fld_comments); - } - 21 => { - mailimf_keywords_free((*field).fld_data.fld_keywords); - } - 22 => { - mailimf_optional_field_free((*field).fld_data.fld_optional_field); - } - _ => {} - } - free(field as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_optional_field_free(mut opt_field: *mut mailimf_optional_field) { - mailimf_field_name_free((*opt_field).fld_name); - mailimf_unstructured_free((*opt_field).fld_value); - free(opt_field as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_unstructured_free(mut unstructured: *mut libc::c_char) { - free(unstructured as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_field_name_free(mut field_name: *mut libc::c_char) { - free(field_name as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_keywords_free(mut keywords: *mut mailimf_keywords) { - clist_foreach( - (*keywords).kw_list, - ::std::mem::transmute:: ()>, clist_func>(Some( - mailimf_phrase_free, - )), - 0 as *mut libc::c_void, - ); - clist_free((*keywords).kw_list); - free(keywords as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_comments_free(mut comments: *mut mailimf_comments) { - mailimf_unstructured_free((*comments).cm_value); - free(comments as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_subject_free(mut subject: *mut mailimf_subject) { - mailimf_unstructured_free((*subject).sbj_value); - free(subject as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_references_free(mut references: *mut mailimf_references) { - clist_foreach( - (*references).mid_list, - ::std::mem::transmute:: ()>, clist_func>(Some( - mailimf_msg_id_free, - )), - 0 as *mut libc::c_void, - ); - clist_free((*references).mid_list); - free(references as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_msg_id_free(mut msg_id: *mut libc::c_char) { - free(msg_id as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_in_reply_to_free(mut in_reply_to: *mut mailimf_in_reply_to) { - clist_foreach( - (*in_reply_to).mid_list, - ::std::mem::transmute:: ()>, clist_func>(Some( - mailimf_msg_id_free, - )), - 0 as *mut libc::c_void, - ); - clist_free((*in_reply_to).mid_list); - free(in_reply_to as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_message_id_free(mut message_id: *mut mailimf_message_id) { - if !(*message_id).mid_value.is_null() { - mailimf_msg_id_free((*message_id).mid_value); - } - free(message_id as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_bcc_free(mut bcc: *mut mailimf_bcc) { - if !(*bcc).bcc_addr_list.is_null() { - mailimf_address_list_free((*bcc).bcc_addr_list); - } - free(bcc as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_cc_free(mut cc: *mut mailimf_cc) { - if !(*cc).cc_addr_list.is_null() { - mailimf_address_list_free((*cc).cc_addr_list); - } - free(cc as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_to_free(mut to: *mut mailimf_to) { - if !(*to).to_addr_list.is_null() { - mailimf_address_list_free((*to).to_addr_list); - } - free(to as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_reply_to_free(mut reply_to: *mut mailimf_reply_to) { - if !(*reply_to).rt_addr_list.is_null() { - mailimf_address_list_free((*reply_to).rt_addr_list); - } - free(reply_to as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_sender_free(mut sender: *mut mailimf_sender) { - if !(*sender).snd_mb.is_null() { - mailimf_mailbox_free((*sender).snd_mb); - } - free(sender as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_from_free(mut from: *mut mailimf_from) { - if !(*from).frm_mb_list.is_null() { - mailimf_mailbox_list_free((*from).frm_mb_list); - } - free(from as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_orig_date_free(mut orig_date: *mut mailimf_orig_date) { - if !(*orig_date).dt_date_time.is_null() { - mailimf_date_time_free((*orig_date).dt_date_time); - } - free(orig_date as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_return_free(mut return_path: *mut mailimf_return) { - mailimf_path_free((*return_path).ret_path); - free(return_path as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_path_free(mut path: *mut mailimf_path) { - if !(*path).pt_addr_spec.is_null() { - mailimf_addr_spec_free((*path).pt_addr_spec); - } - free(path as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_fields_new(mut fld_list: *mut clist) -> *mut mailimf_fields { - let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; - fields = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_fields; - if fields.is_null() { - return 0 as *mut mailimf_fields; - } - (*fields).fld_list = fld_list; - return fields; -} - -#[no_mangle] -pub unsafe fn mailimf_field_new( - mut fld_type: libc::c_int, - mut fld_return_path: *mut mailimf_return, - mut fld_resent_date: *mut mailimf_orig_date, - mut fld_resent_from: *mut mailimf_from, - mut fld_resent_sender: *mut mailimf_sender, - mut fld_resent_to: *mut mailimf_to, - mut fld_resent_cc: *mut mailimf_cc, - mut fld_resent_bcc: *mut mailimf_bcc, - mut fld_resent_msg_id: *mut mailimf_message_id, - mut fld_orig_date: *mut mailimf_orig_date, - mut fld_from: *mut mailimf_from, - mut fld_sender: *mut mailimf_sender, - mut fld_reply_to: *mut mailimf_reply_to, - mut fld_to: *mut mailimf_to, - mut fld_cc: *mut mailimf_cc, - mut fld_bcc: *mut mailimf_bcc, - mut fld_message_id: *mut mailimf_message_id, - mut fld_in_reply_to: *mut mailimf_in_reply_to, - mut fld_references: *mut mailimf_references, - mut fld_subject: *mut mailimf_subject, - mut fld_comments: *mut mailimf_comments, - mut fld_keywords: *mut mailimf_keywords, - mut fld_optional_field: *mut mailimf_optional_field, -) -> *mut mailimf_field { - let mut field: *mut mailimf_field = 0 as *mut mailimf_field; - field = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_field; - if field.is_null() { - return 0 as *mut mailimf_field; - } - (*field).fld_type = fld_type; - match fld_type { - 1 => (*field).fld_data.fld_return_path = fld_return_path, - 2 => (*field).fld_data.fld_resent_date = fld_resent_date, - 3 => (*field).fld_data.fld_resent_from = fld_resent_from, - 4 => (*field).fld_data.fld_resent_sender = fld_resent_sender, - 5 => (*field).fld_data.fld_resent_to = fld_resent_to, - 6 => (*field).fld_data.fld_resent_cc = fld_resent_cc, - 7 => (*field).fld_data.fld_resent_bcc = fld_resent_bcc, - 8 => (*field).fld_data.fld_resent_msg_id = fld_resent_msg_id, - 9 => (*field).fld_data.fld_orig_date = fld_orig_date, - 10 => (*field).fld_data.fld_from = fld_from, - 11 => (*field).fld_data.fld_sender = fld_sender, - 12 => (*field).fld_data.fld_reply_to = fld_reply_to, - 13 => (*field).fld_data.fld_to = fld_to, - 14 => (*field).fld_data.fld_cc = fld_cc, - 15 => (*field).fld_data.fld_bcc = fld_bcc, - 16 => (*field).fld_data.fld_message_id = fld_message_id, - 17 => (*field).fld_data.fld_in_reply_to = fld_in_reply_to, - 18 => (*field).fld_data.fld_references = fld_references, - 19 => (*field).fld_data.fld_subject = fld_subject, - 20 => (*field).fld_data.fld_comments = fld_comments, - 21 => (*field).fld_data.fld_keywords = fld_keywords, - 22 => (*field).fld_data.fld_optional_field = fld_optional_field, - _ => {} - } - return field; -} - -#[no_mangle] -pub unsafe fn mailimf_field_new_subject(fld_subject: *mut mailimf_subject) -> *mut mailimf_field { - let mut field: *mut mailimf_field = 0 as *mut mailimf_field; - field = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_field; - if field.is_null() { - return 0 as *mut mailimf_field; - } - (*field).fld_type = MAILIMF_FIELD_SUBJECT as libc::c_int; - (*field).fld_data.fld_subject = fld_subject; - - field -} - -#[no_mangle] -pub unsafe fn mailimf_orig_date_new( - mut dt_date_time: *mut mailimf_date_time, -) -> *mut mailimf_orig_date { - let mut orig_date: *mut mailimf_orig_date = 0 as *mut mailimf_orig_date; - orig_date = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailimf_orig_date; - if orig_date.is_null() { - return 0 as *mut mailimf_orig_date; - } - (*orig_date).dt_date_time = dt_date_time; - return orig_date; -} -#[no_mangle] -pub unsafe fn mailimf_from_new(mut frm_mb_list: *mut mailimf_mailbox_list) -> *mut mailimf_from { - let mut from: *mut mailimf_from = 0 as *mut mailimf_from; - from = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_from; - if from.is_null() { - return 0 as *mut mailimf_from; - } - (*from).frm_mb_list = frm_mb_list; - return from; -} -#[no_mangle] -pub unsafe fn mailimf_sender_new(mut snd_mb: *mut mailimf_mailbox) -> *mut mailimf_sender { - let mut sender: *mut mailimf_sender = 0 as *mut mailimf_sender; - sender = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_sender; - if sender.is_null() { - return 0 as *mut mailimf_sender; - } - (*sender).snd_mb = snd_mb; - return sender; -} -#[no_mangle] -pub unsafe fn mailimf_reply_to_new( - mut rt_addr_list: *mut mailimf_address_list, -) -> *mut mailimf_reply_to { - let mut reply_to: *mut mailimf_reply_to = 0 as *mut mailimf_reply_to; - reply_to = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_reply_to; - if reply_to.is_null() { - return 0 as *mut mailimf_reply_to; - } - (*reply_to).rt_addr_list = rt_addr_list; - return reply_to; -} -#[no_mangle] -pub unsafe fn mailimf_to_new(mut to_addr_list: *mut mailimf_address_list) -> *mut mailimf_to { - let mut to: *mut mailimf_to = 0 as *mut mailimf_to; - to = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_to; - if to.is_null() { - return 0 as *mut mailimf_to; - } - (*to).to_addr_list = to_addr_list; - return to; -} -#[no_mangle] -pub unsafe fn mailimf_cc_new(mut cc_addr_list: *mut mailimf_address_list) -> *mut mailimf_cc { - let mut cc: *mut mailimf_cc = 0 as *mut mailimf_cc; - cc = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_cc; - if cc.is_null() { - return 0 as *mut mailimf_cc; - } - (*cc).cc_addr_list = cc_addr_list; - return cc; -} -#[no_mangle] -pub unsafe fn mailimf_bcc_new(mut bcc_addr_list: *mut mailimf_address_list) -> *mut mailimf_bcc { - let mut bcc: *mut mailimf_bcc = 0 as *mut mailimf_bcc; - bcc = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_bcc; - if bcc.is_null() { - return 0 as *mut mailimf_bcc; - } - (*bcc).bcc_addr_list = bcc_addr_list; - return bcc; -} -#[no_mangle] -pub unsafe fn mailimf_message_id_new(mut mid_value: *mut libc::c_char) -> *mut mailimf_message_id { - let mut message_id: *mut mailimf_message_id = 0 as *mut mailimf_message_id; - message_id = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailimf_message_id; - if message_id.is_null() { - return 0 as *mut mailimf_message_id; - } - (*message_id).mid_value = mid_value; - return message_id; -} -#[no_mangle] -pub unsafe fn mailimf_in_reply_to_new(mut mid_list: *mut clist) -> *mut mailimf_in_reply_to { - let mut in_reply_to: *mut mailimf_in_reply_to = 0 as *mut mailimf_in_reply_to; - in_reply_to = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailimf_in_reply_to; - if in_reply_to.is_null() { - return 0 as *mut mailimf_in_reply_to; - } - (*in_reply_to).mid_list = mid_list; - return in_reply_to; -} -/* != NULL */ -#[no_mangle] -pub unsafe fn mailimf_references_new(mut mid_list: *mut clist) -> *mut mailimf_references { - let mut ref_0: *mut mailimf_references = 0 as *mut mailimf_references; - ref_0 = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailimf_references; - if ref_0.is_null() { - return 0 as *mut mailimf_references; - } - (*ref_0).mid_list = mid_list; - return ref_0; -} -#[no_mangle] -pub unsafe fn mailimf_subject_new(mut sbj_value: *mut libc::c_char) -> *mut mailimf_subject { - let mut subject: *mut mailimf_subject = 0 as *mut mailimf_subject; - subject = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_subject; - if subject.is_null() { - return 0 as *mut mailimf_subject; - } - (*subject).sbj_value = sbj_value; - return subject; -} -#[no_mangle] -pub unsafe fn mailimf_comments_new(mut cm_value: *mut libc::c_char) -> *mut mailimf_comments { - let mut comments: *mut mailimf_comments = 0 as *mut mailimf_comments; - comments = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_comments; - if comments.is_null() { - return 0 as *mut mailimf_comments; - } - (*comments).cm_value = cm_value; - return comments; -} -#[no_mangle] -pub unsafe fn mailimf_keywords_new(mut kw_list: *mut clist) -> *mut mailimf_keywords { - let mut keywords: *mut mailimf_keywords = 0 as *mut mailimf_keywords; - keywords = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_keywords; - if keywords.is_null() { - return 0 as *mut mailimf_keywords; - } - (*keywords).kw_list = kw_list; - return keywords; -} -#[no_mangle] -pub unsafe fn mailimf_return_new(mut ret_path: *mut mailimf_path) -> *mut mailimf_return { - let mut return_path: *mut mailimf_return = 0 as *mut mailimf_return; - return_path = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_return; - if return_path.is_null() { - return 0 as *mut mailimf_return; - } - (*return_path).ret_path = ret_path; - return return_path; -} -#[no_mangle] -pub unsafe fn mailimf_path_new(mut pt_addr_spec: *mut libc::c_char) -> *mut mailimf_path { - let mut path: *mut mailimf_path = 0 as *mut mailimf_path; - path = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailimf_path; - if path.is_null() { - return 0 as *mut mailimf_path; - } - (*path).pt_addr_spec = pt_addr_spec; - return path; -} -#[no_mangle] -pub unsafe fn mailimf_optional_field_new( - mut fld_name: *mut libc::c_char, - mut fld_value: *mut libc::c_char, -) -> *mut mailimf_optional_field { - let mut opt_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field; - opt_field = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailimf_optional_field; - if opt_field.is_null() { - return 0 as *mut mailimf_optional_field; - } - (*opt_field).fld_name = fld_name; - (*opt_field).fld_value = fld_value; - return opt_field; -} -/* internal use */ -#[no_mangle] -pub unsafe fn mailimf_atom_free(mut atom: *mut libc::c_char) { - free(atom as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_dot_atom_free(mut dot_atom: *mut libc::c_char) { - free(dot_atom as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_dot_atom_text_free(mut dot_atom: *mut libc::c_char) { - free(dot_atom as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_quoted_string_free(mut quoted_string: *mut libc::c_char) { - free(quoted_string as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_word_free(mut word: *mut libc::c_char) { - free(word as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_angle_addr_free(mut angle_addr: *mut libc::c_char) { - free(angle_addr as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_local_part_free(mut local_part: *mut libc::c_char) { - free(local_part as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_domain_free(mut domain: *mut libc::c_char) { - free(domain as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_domain_literal_free(mut domain_literal: *mut libc::c_char) { - free(domain_literal as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_id_left_free(mut id_left: *mut libc::c_char) { - free(id_left as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_id_right_free(mut id_right: *mut libc::c_char) { - free(id_right as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_no_fold_quote_free(mut nfq: *mut libc::c_char) { - free(nfq as *mut libc::c_void); -} -#[no_mangle] -pub unsafe fn mailimf_no_fold_literal_free(mut nfl: *mut libc::c_char) { - free(nfl as *mut libc::c_void); -} diff --git a/mmime/src/mailimf/types_helper.rs b/mmime/src/mailimf/types_helper.rs deleted file mode 100644 index 8701559b1..000000000 --- a/mmime/src/mailimf/types_helper.rs +++ /dev/null @@ -1,89 +0,0 @@ -use crate::clist::*; -use crate::mailimf::types::*; -use crate::other::*; - -/* - this function creates a new mailimf_fields structure with no fields -*/ -pub unsafe fn mailimf_fields_new_empty() -> *mut mailimf_fields { - let mut list: *mut clist = 0 as *mut clist; - let mut fields_list: *mut mailimf_fields = 0 as *mut mailimf_fields; - list = clist_new(); - if list.is_null() { - return 0 as *mut mailimf_fields; - } - fields_list = mailimf_fields_new(list); - if fields_list.is_null() { - return 0 as *mut mailimf_fields; - } - return fields_list; -} -/* - this function adds a field to the mailimf_fields structure - - @return MAILIMF_NO_ERROR will be returned on success, - other code will be returned otherwise -*/ -pub unsafe fn mailimf_fields_add( - mut fields: *mut mailimf_fields, - mut field: *mut mailimf_field, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = clist_insert_after( - (*fields).fld_list, - (*(*fields).fld_list).last, - field as *mut libc::c_void, - ); - if r < 0i32 { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - return MAILIMF_NO_ERROR as libc::c_int; -} - -/* - mailimf_field_new_custom creates a new field of type optional - - @param name should be allocated with malloc() - @param value should be allocated with malloc() -*/ -pub unsafe fn mailimf_field_new_custom( - mut name: *mut libc::c_char, - mut value: *mut libc::c_char, -) -> *mut mailimf_field { - let mut opt_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field; - let mut field: *mut mailimf_field = 0 as *mut mailimf_field; - opt_field = mailimf_optional_field_new(name, value); - if !opt_field.is_null() { - field = mailimf_field_new( - MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_reply_to, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_in_reply_to, - 0 as *mut mailimf_references, - 0 as *mut mailimf_subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - opt_field, - ); - if field.is_null() { - mailimf_optional_field_free(opt_field); - } else { - return field; - } - } - return 0 as *mut mailimf_field; -} diff --git a/mmime/src/mailimf/write_generic.rs b/mmime/src/mailimf/write_generic.rs deleted file mode 100644 index a449fd60e..000000000 --- a/mmime/src/mailimf/write_generic.rs +++ /dev/null @@ -1,1985 +0,0 @@ -use crate::clist::*; -use crate::mailimf::types::*; -use crate::other::*; - -pub const STATE_WORD: libc::c_uint = 1; -pub const STATE_SPACE: libc::c_uint = 2; -pub const STATE_BEGIN: libc::c_uint = 0; - -/* - mailimf_string_write writes a string to a given stream - - @param f is the stream - @param col (* col) is the column number where we will start to - write the text, the ending column will be stored in (* col) - @param str is the string to write -*/ -pub unsafe fn mailimf_string_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut str: *const libc::c_char, - mut length: size_t, -) -> libc::c_int { - let mut r: libc::c_int = 0; - let mut count: size_t = 0; - let mut block_begin: *const libc::c_char = 0 as *const libc::c_char; - let mut p: *const libc::c_char = 0 as *const libc::c_char; - let mut done: libc::c_int = 0; - p = str; - block_begin = str; - count = 0i32 as size_t; - while length > 0i32 as libc::size_t { - if count >= 998i32 as libc::size_t { - r = flush_buf(do_write, data, block_begin, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = do_write.expect("non-null function pointer")( - data, - b"\r\n\x00" as *const u8 as *const libc::c_char, - (::std::mem::size_of::<[libc::c_char; 3]>() as libc::size_t) - .wrapping_sub(1i32 as libc::size_t), - ); - if r == 0i32 { - return MAILIMF_ERROR_FILE as libc::c_int; - } - count = 0i32 as size_t; - block_begin = p; - *col = 0i32 - } - match *p as libc::c_int { - 10 => { - r = flush_buf(do_write, data, block_begin, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = do_write.expect("non-null function pointer")( - data, - b"\r\n\x00" as *const u8 as *const libc::c_char, - (::std::mem::size_of::<[libc::c_char; 3]>() as libc::size_t) - .wrapping_sub(1i32 as libc::size_t), - ); - if r == 0i32 { - return MAILIMF_ERROR_FILE as libc::c_int; - } - p = p.offset(1isize); - length = length.wrapping_sub(1); - count = 0i32 as size_t; - block_begin = p; - *col = 0i32 - } - 13 => { - done = 0i32; - if length >= 2i32 as libc::size_t { - if *p.offset(1isize) as libc::c_int == '\n' as i32 { - r = flush_buf(do_write, data, block_begin, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = do_write.expect("non-null function pointer")( - data, - b"\r\n\x00" as *const u8 as *const libc::c_char, - (::std::mem::size_of::<[libc::c_char; 3]>() as libc::size_t) - .wrapping_sub(1i32 as libc::size_t), - ); - if r == 0i32 { - return MAILIMF_ERROR_FILE as libc::c_int; - } - p = p.offset(2isize); - length = (length as libc::size_t).wrapping_sub(2i32 as libc::size_t) - as size_t as size_t; - count = 0i32 as size_t; - block_begin = p; - *col = 0i32; - done = 1i32 - } - } - if 0 == done { - r = flush_buf(do_write, data, block_begin, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = do_write.expect("non-null function pointer")( - data, - b"\r\n\x00" as *const u8 as *const libc::c_char, - (::std::mem::size_of::<[libc::c_char; 3]>() as libc::size_t) - .wrapping_sub(1i32 as libc::size_t), - ); - if r == 0i32 { - return MAILIMF_ERROR_FILE as libc::c_int; - } - p = p.offset(1isize); - length = length.wrapping_sub(1); - count = 0i32 as size_t; - block_begin = p; - *col = 0i32 - } - } - _ => { - p = p.offset(1isize); - count = count.wrapping_add(1); - length = length.wrapping_sub(1) - } - } - } - r = flush_buf(do_write, data, block_begin, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *col = (*col as libc::size_t).wrapping_add(count) as libc::c_int as libc::c_int; - return MAILIMF_NO_ERROR as libc::c_int; -} -/* ************************ */ -#[inline] -unsafe fn flush_buf( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut str: *const libc::c_char, - mut length: size_t, -) -> libc::c_int { - if length != 0i32 as libc::size_t { - let mut r: libc::c_int = 0; - if length > 0i32 as libc::size_t { - r = do_write.expect("non-null function pointer")(data, str, length); - if r == 0i32 { - return MAILIMF_ERROR_FILE as libc::c_int; - } - } - } - return MAILIMF_NO_ERROR as libc::c_int; -} -/* - mailimf_fields_write writes the fields to a given stream - - @param f is the stream - @param col (* col) is the column number where we will start to - write the text, the ending column will be stored in (* col) - @param fields is the fields to write -*/ - -pub unsafe fn mailimf_fields_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut fields: *mut mailimf_fields, -) -> libc::c_int { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*fields).fld_list).first; - while !cur.is_null() { - let mut r: libc::c_int = 0; - r = mailimf_field_write_driver( - do_write, - data, - col, - (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailimf_field, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - return MAILIMF_NO_ERROR as libc::c_int; -} -/* - mailimf_field_write writes a field to a given stream - - @param f is the stream - @param col (* col) is the column number where we will start to - write the text, the ending column will be stored in (* col) - @param field is the field to write -*/ -pub unsafe fn mailimf_field_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut field: *mut mailimf_field, -) -> libc::c_int { - let mut r: libc::c_int = 0; - match (*field).fld_type { - 1 => { - r = mailimf_return_write_driver(do_write, data, col, (*field).fld_data.fld_return_path) - } - 2 => { - r = mailimf_resent_date_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_resent_date, - ) - } - 3 => { - r = mailimf_resent_from_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_resent_from, - ) - } - 4 => { - r = mailimf_resent_sender_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_resent_sender, - ) - } - 5 => { - r = mailimf_resent_to_write_driver(do_write, data, col, (*field).fld_data.fld_resent_to) - } - 6 => { - r = mailimf_resent_cc_write_driver(do_write, data, col, (*field).fld_data.fld_resent_cc) - } - 7 => { - r = mailimf_resent_bcc_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_resent_bcc, - ) - } - 8 => { - r = mailimf_resent_msg_id_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_resent_msg_id, - ) - } - 9 => { - r = mailimf_orig_date_write_driver(do_write, data, col, (*field).fld_data.fld_orig_date) - } - 10 => r = mailimf_from_write_driver(do_write, data, col, (*field).fld_data.fld_from), - 11 => r = mailimf_sender_write_driver(do_write, data, col, (*field).fld_data.fld_sender), - 12 => { - r = mailimf_reply_to_write_driver(do_write, data, col, (*field).fld_data.fld_reply_to) - } - 13 => r = mailimf_to_write_driver(do_write, data, col, (*field).fld_data.fld_to), - 14 => r = mailimf_cc_write_driver(do_write, data, col, (*field).fld_data.fld_cc), - 15 => r = mailimf_bcc_write_driver(do_write, data, col, (*field).fld_data.fld_bcc), - 16 => { - r = mailimf_message_id_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_message_id, - ) - } - 17 => { - r = mailimf_in_reply_to_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_in_reply_to, - ) - } - 18 => { - r = mailimf_references_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_references, - ) - } - 19 => r = mailimf_subject_write_driver(do_write, data, col, (*field).fld_data.fld_subject), - 20 => { - r = mailimf_comments_write_driver(do_write, data, col, (*field).fld_data.fld_comments) - } - 21 => { - r = mailimf_keywords_write_driver(do_write, data, col, (*field).fld_data.fld_keywords) - } - 22 => { - r = mailimf_optional_field_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_optional_field, - ) - } - _ => r = MAILIMF_ERROR_INVAL as libc::c_int, - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_optional_field_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut field: *mut mailimf_optional_field, -) -> libc::c_int { - let mut r: libc::c_int = 0; - if strlen((*field).fld_name).wrapping_add(2i32 as libc::size_t) > 998i32 as libc::size_t { - return MAILIMF_ERROR_INVAL as libc::c_int; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - (*field).fld_name, - strlen((*field).fld_name), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b": \x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_header_string_write_driver( - do_write, - data, - col, - (*field).fld_value, - strlen((*field).fld_value), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -/* - mailimf_header_string_write writes a header value and fold the header - if needed. - - @param f is the stream - @param col (* col) is the column number where we will start to - write the text, the ending column will be stored in (* col) - @param str is the string to write -*/ -pub unsafe fn mailimf_header_string_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut str: *const libc::c_char, - mut length: size_t, -) -> libc::c_int { - let mut state: libc::c_int = 0; - let mut p: *const libc::c_char = 0 as *const libc::c_char; - let mut word_begin: *const libc::c_char = 0 as *const libc::c_char; - let mut first: libc::c_int = 0; - state = STATE_BEGIN as libc::c_int; - p = str; - word_begin = p; - first = 1i32; - while length > 0i32 as libc::size_t { - match state { - 0 => match *p as libc::c_int { - 13 | 10 | 32 | 9 => { - p = p.offset(1isize); - length = length.wrapping_sub(1) - } - _ => { - word_begin = p; - state = STATE_WORD as libc::c_int - } - }, - 2 => match *p as libc::c_int { - 13 | 10 | 32 | 9 => { - p = p.offset(1isize); - length = length.wrapping_sub(1) - } - _ => { - word_begin = p; - state = STATE_WORD as libc::c_int - } - }, - 1 => match *p as libc::c_int { - 13 | 10 | 32 | 9 => { - if p.wrapping_offset_from(word_begin) as libc::c_int - + *col as libc::c_int - + 1i32 as libc::c_int - > 72i32 as libc::c_int - { - mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - (::std::mem::size_of::<[libc::c_char; 4]>() as libc::size_t) - .wrapping_sub(1i32 as libc::size_t), - ); - } else if 0 == first { - mailimf_string_write_driver( - do_write, - data, - col, - b" \x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - } - first = 0i32; - mailimf_string_write_driver( - do_write, - data, - col, - word_begin, - p.wrapping_offset_from(word_begin) as libc::c_int as size_t, - ); - state = STATE_SPACE as libc::c_int - } - _ => { - if p.wrapping_offset_from(word_begin) as libc::c_int + *col as libc::c_int - >= 998i32 as libc::c_int - { - mailimf_string_write_driver( - do_write, - data, - col, - word_begin, - p.wrapping_offset_from(word_begin) as libc::c_int as size_t, - ); - mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - (::std::mem::size_of::<[libc::c_char; 4]>() as libc::size_t) - .wrapping_sub(1i32 as libc::size_t), - ); - word_begin = p - } - p = p.offset(1isize); - length = length.wrapping_sub(1) - } - }, - _ => {} - } - } - if state == STATE_WORD as libc::c_int { - if p.wrapping_offset_from(word_begin) as libc::c_int + *col as libc::c_int - >= 72i32 as libc::c_int - { - mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - (::std::mem::size_of::<[libc::c_char; 4]>() as libc::size_t) - .wrapping_sub(1i32 as libc::size_t), - ); - } else if 0 == first { - mailimf_string_write_driver( - do_write, - data, - col, - b" \x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - } - first = 0i32; - mailimf_string_write_driver( - do_write, - data, - col, - word_begin, - p.wrapping_offset_from(word_begin) as libc::c_int as size_t, - ); - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_keywords_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut keywords: *mut mailimf_keywords, -) -> libc::c_int { - let mut r: libc::c_int = 0; - let mut cur: *mut clistiter = 0 as *mut clistiter; - let mut first: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Keywords: \x00" as *const u8 as *const libc::c_char, - 10i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - first = 1i32; - cur = (*(*keywords).kw_list).first; - while !cur.is_null() { - let mut keyword: *mut libc::c_char = 0 as *mut libc::c_char; - let mut len: size_t = 0; - keyword = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut libc::c_char; - len = strlen(keyword); - if 0 == first { - r = mailimf_string_write_driver( - do_write, - data, - col, - b", \x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } else { - first = 0i32 - } - r = mailimf_header_string_write_driver(do_write, data, col, keyword, len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_comments_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut comments: *mut mailimf_comments, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Comments: \x00" as *const u8 as *const libc::c_char, - 10i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_header_string_write_driver( - do_write, - data, - col, - (*comments).cm_value, - strlen((*comments).cm_value), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_subject_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut subject: *mut mailimf_subject, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Subject: \x00" as *const u8 as *const libc::c_char, - 9i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_header_string_write_driver( - do_write, - data, - col, - (*subject).sbj_value, - strlen((*subject).sbj_value), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_references_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut references: *mut mailimf_references, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"References: \x00" as *const u8 as *const libc::c_char, - 12i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_msg_id_list_write_driver(do_write, data, col, (*references).mid_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_msg_id_list_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut mid_list: *mut clist, -) -> libc::c_int { - let mut cur: *mut clistiter = 0 as *mut clistiter; - let mut r: libc::c_int = 0; - let mut first: libc::c_int = 0; - first = 1i32; - cur = (*mid_list).first; - while !cur.is_null() { - let mut msgid: *mut libc::c_char = 0 as *mut libc::c_char; - let mut len: size_t = 0; - msgid = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut libc::c_char; - len = strlen(msgid); - if 0 == first { - if *col > 1i32 { - if (*col as libc::size_t).wrapping_add(len) >= 72i32 as libc::size_t { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - first = 1i32 - } - } - } - if 0 == first { - r = mailimf_string_write_driver( - do_write, - data, - col, - b" \x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } else { - first = 0i32 - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"<\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver(do_write, data, col, msgid, len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b">\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_in_reply_to_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut in_reply_to: *mut mailimf_in_reply_to, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"In-Reply-To: \x00" as *const u8 as *const libc::c_char, - 13i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_msg_id_list_write_driver(do_write, data, col, (*in_reply_to).mid_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_message_id_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut message_id: *mut mailimf_message_id, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Message-ID: \x00" as *const u8 as *const libc::c_char, - 12i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"<\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - (*message_id).mid_value, - strlen((*message_id).mid_value), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b">\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_bcc_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut bcc: *mut mailimf_bcc, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Bcc: \x00" as *const u8 as *const libc::c_char, - 5i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - if !(*bcc).bcc_addr_list.is_null() { - r = mailimf_address_list_write_driver(do_write, data, col, (*bcc).bcc_addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -pub unsafe fn mailimf_address_list_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut addr_list: *mut mailimf_address_list, -) -> libc::c_int { - let mut cur: *mut clistiter = 0 as *mut clistiter; - let mut r: libc::c_int = 0; - let mut first: libc::c_int = 0; - first = 1i32; - cur = (*(*addr_list).ad_list).first; - while !cur.is_null() { - let mut addr: *mut mailimf_address = 0 as *mut mailimf_address; - addr = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailimf_address; - if 0 == first { - r = mailimf_string_write_driver( - do_write, - data, - col, - b", \x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } else { - first = 0i32 - } - r = mailimf_address_write_driver(do_write, data, col, addr); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_address_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut addr: *mut mailimf_address, -) -> libc::c_int { - let mut r: libc::c_int = 0; - match (*addr).ad_type { - 1 => { - r = mailimf_mailbox_write_driver(do_write, data, col, (*addr).ad_data.ad_mailbox); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 2 => { - r = mailimf_group_write_driver(do_write, data, col, (*addr).ad_data.ad_group); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - _ => {} - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_group_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut group: *mut mailimf_group, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_header_string_write_driver( - do_write, - data, - col, - (*group).grp_display_name, - strlen((*group).grp_display_name), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b": \x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - if !(*group).grp_mb_list.is_null() { - r = mailimf_mailbox_list_write_driver(do_write, data, col, (*group).grp_mb_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b";\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailimf_mailbox_list_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut mb_list: *mut mailimf_mailbox_list, -) -> libc::c_int { - let mut cur: *mut clistiter = 0 as *mut clistiter; - let mut r: libc::c_int = 0; - let mut first: libc::c_int = 0; - first = 1i32; - cur = (*(*mb_list).mb_list).first; - while !cur.is_null() { - let mut mb: *mut mailimf_mailbox = 0 as *mut mailimf_mailbox; - mb = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailimf_mailbox; - if 0 == first { - r = mailimf_string_write_driver( - do_write, - data, - col, - b", \x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } else { - first = 0i32 - } - r = mailimf_mailbox_write_driver(do_write, data, col, mb); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_mailbox_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut mb: *mut mailimf_mailbox, -) -> libc::c_int { - let mut r: libc::c_int = 0; - let mut do_fold: libc::c_int = 0; - if !(*mb).mb_display_name.is_null() { - if 0 != is_atext((*mb).mb_display_name) { - r = mailimf_header_string_write_driver( - do_write, - data, - col, - (*mb).mb_display_name, - strlen((*mb).mb_display_name), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } else { - if !(*mb).mb_display_name.is_null() { - if (*col as libc::size_t).wrapping_add(strlen((*mb).mb_display_name)) - >= 72i32 as libc::size_t - { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - } - if strlen((*mb).mb_display_name) > (998i32 / 2i32) as libc::size_t { - return MAILIMF_ERROR_INVAL as libc::c_int; - } - r = mailimf_quoted_string_write_driver( - do_write, - data, - col, - (*mb).mb_display_name, - strlen((*mb).mb_display_name), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - do_fold = 0i32; - if *col > 1i32 { - if (*col as libc::size_t) - .wrapping_add(strlen((*mb).mb_addr_spec)) - .wrapping_add(3i32 as libc::size_t) - >= 72i32 as libc::size_t - { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - do_fold = 1i32 - } - } - if 0 != do_fold { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"<\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ) - } else { - r = mailimf_string_write_driver( - do_write, - data, - col, - b" <\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ) - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - (*mb).mb_addr_spec, - strlen((*mb).mb_addr_spec), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b">\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } else { - if (*col as libc::size_t).wrapping_add(strlen((*mb).mb_addr_spec)) >= 72i32 as libc::size_t - { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - r = mailimf_string_write_driver( - do_write, - data, - col, - (*mb).mb_addr_spec, - strlen((*mb).mb_addr_spec), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - return MAILIMF_NO_ERROR as libc::c_int; -} -/* - mailimf_quoted_string_write writes a string that is quoted - to a given stream - - @param f is the stream - @param col (* col) is the column number where we will start to - write the text, the ending column will be stored in (* col) - @param string is the string to quote and write -*/ -pub unsafe fn mailimf_quoted_string_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut string: *const libc::c_char, - mut len: size_t, -) -> libc::c_int { - let mut r: libc::c_int = 0; - let mut i: size_t = 0; - r = do_write.expect("non-null function pointer")( - data, - b"\"\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r == 0i32 { - return MAILIMF_ERROR_FILE as libc::c_int; - } - i = 0i32 as size_t; - while i < len { - match *string.offset(i as isize) as libc::c_int { - 92 | 34 => { - r = do_write.expect("non-null function pointer")( - data, - b"\\\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r == 0i32 { - return MAILIMF_ERROR_FILE as libc::c_int; - } - r = do_write.expect("non-null function pointer")( - data, - &*string.offset(i as isize), - 1i32 as size_t, - ); - if r == 0i32 { - return MAILIMF_ERROR_FILE as libc::c_int; - } - *col += 2i32 - } - _ => { - r = do_write.expect("non-null function pointer")( - data, - &*string.offset(i as isize), - 1i32 as size_t, - ); - if r == 0i32 { - return MAILIMF_ERROR_FILE as libc::c_int; - } - *col += 1 - } - } - i = i.wrapping_add(1) - } - r = do_write.expect("non-null function pointer")( - data, - b"\"\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r == 0i32 { - return MAILIMF_ERROR_FILE as libc::c_int; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -/* -static int -atext = ALPHA / DIGIT / ; Any character except controls, - "!" / "#" / ; SP, and specials. - "$" / "%" / ; Used for atoms - "&" / "'" / - "*" / "+" / - "-" / "/" / - "=" / "?" / - "^" / "_" / - "`" / "{" / - "|" / "}" / - "~" -*/ -unsafe fn is_atext(mut s: *const libc::c_char) -> libc::c_int { - let mut p: *const libc::c_char = 0 as *const libc::c_char; - p = s; - while *p as libc::c_int != 0i32 { - if !(0 != isalpha(*p as libc::c_uchar as libc::c_int)) { - if !(0 != isdigit(*p as libc::c_uchar as libc::c_int)) { - match *p as libc::c_int { - 32 | 9 | 33 | 35 | 36 | 37 | 38 | 39 | 42 | 43 | 45 | 47 | 61 | 63 | 94 - | 95 | 96 | 123 | 124 | 125 | 126 => {} - _ => return 0i32, - } - } - } - p = p.offset(1isize) - } - return 1i32; -} - -unsafe fn mailimf_cc_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut cc: *mut mailimf_cc, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Cc: \x00" as *const u8 as *const libc::c_char, - 4i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_address_list_write_driver(do_write, data, col, (*cc).cc_addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_to_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut to: *mut mailimf_to, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"To: \x00" as *const u8 as *const libc::c_char, - 4i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_address_list_write_driver(do_write, data, col, (*to).to_addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_reply_to_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut reply_to: *mut mailimf_reply_to, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Reply-To: \x00" as *const u8 as *const libc::c_char, - 10i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_address_list_write_driver(do_write, data, col, (*reply_to).rt_addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_sender_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut sender: *mut mailimf_sender, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Sender: \x00" as *const u8 as *const libc::c_char, - 8i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_mailbox_write_driver(do_write, data, col, (*sender).snd_mb); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_from_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut from: *mut mailimf_from, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"From: \x00" as *const u8 as *const libc::c_char, - 6i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_mailbox_list_write_driver(do_write, data, col, (*from).frm_mb_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -/* - * libEtPan! -- a mail stuff library - * - * Copyright (C) 2001, 2005 - DINH Viet Hoa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the libEtPan! project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * $Id: mailimf_write_generic.c,v 1.3 2006/05/22 13:39:42 hoa Exp $ - */ -unsafe fn mailimf_orig_date_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut date: *mut mailimf_orig_date, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Date: \x00" as *const u8 as *const libc::c_char, - 6i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_date_time_write_driver(do_write, data, col, (*date).dt_date_time); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_date_time_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut date_time: *mut mailimf_date_time, -) -> libc::c_int { - let wday = dayofweek( - (*date_time).dt_year, - (*date_time).dt_month, - (*date_time).dt_day, - ); - - let date_str = format!( - "{}, {} {} {} {:02}:{:02}:{:02} {:+05}", - week_of_day_str[wday as usize], - (*date_time).dt_day, - month_str[((*date_time).dt_month - 1i32) as usize], - (*date_time).dt_year, - (*date_time).dt_hour, - (*date_time).dt_min, - (*date_time).dt_sec, - (*date_time).dt_zone, - ); - let date_str_c = std::ffi::CString::new(date_str).unwrap_or_default(); - let r = mailimf_string_write_driver( - do_write, - data, - col, - date_str_c.as_ptr() as *mut _, - strlen(date_str_c.as_ptr()), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -static mut month_str: [&'static str; 12] = [ - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", -]; -static mut week_of_day_str: [&'static str; 7] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; -/* 0 = Sunday */ -/* y > 1752 */ -unsafe fn dayofweek( - mut year: libc::c_int, - mut month: libc::c_int, - mut day: libc::c_int, -) -> libc::c_int { - static mut offset: [libc::c_int; 12] = [ - 0i32, 3i32, 2i32, 5i32, 0i32, 3i32, 5i32, 1i32, 4i32, 6i32, 2i32, 4i32, - ]; - year -= (month < 3i32) as libc::c_int; - return (year + year / 4i32 - year / 100i32 - + year / 400i32 - + offset[(month - 1i32) as usize] - + day) - % 7i32; -} -unsafe fn mailimf_resent_msg_id_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut message_id: *mut mailimf_message_id, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Resent-Message-ID: \x00" as *const u8 as *const libc::c_char, - 19i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"<\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - (*message_id).mid_value, - strlen((*message_id).mid_value), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b">\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_resent_bcc_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut bcc: *mut mailimf_bcc, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Resent-Bcc: \x00" as *const u8 as *const libc::c_char, - 12i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - if !(*bcc).bcc_addr_list.is_null() { - r = mailimf_address_list_write_driver(do_write, data, col, (*bcc).bcc_addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_resent_cc_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut cc: *mut mailimf_cc, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Resent-Cc: \x00" as *const u8 as *const libc::c_char, - 11i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_address_list_write_driver(do_write, data, col, (*cc).cc_addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_resent_to_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut to: *mut mailimf_to, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Resent-To: \x00" as *const u8 as *const libc::c_char, - 11i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_address_list_write_driver(do_write, data, col, (*to).to_addr_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_resent_sender_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut sender: *mut mailimf_sender, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Resent-Sender: \x00" as *const u8 as *const libc::c_char, - 15i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_mailbox_write_driver(do_write, data, col, (*sender).snd_mb); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_resent_from_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut from: *mut mailimf_from, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Resent-From: \x00" as *const u8 as *const libc::c_char, - 13i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_mailbox_list_write_driver(do_write, data, col, (*from).frm_mb_list); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_resent_date_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut date: *mut mailimf_orig_date, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Resent-Date: \x00" as *const u8 as *const libc::c_char, - 13i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_date_time_write_driver(do_write, data, col, (*date).dt_date_time); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_return_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut return_path: *mut mailimf_return, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Return-Path: \x00" as *const u8 as *const libc::c_char, - 13i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_path_write_driver(do_write, data, col, (*return_path).ret_path); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailimf_path_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut path: *mut mailimf_path, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"<\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - if !(*path).pt_addr_spec.is_null() { - r = mailimf_string_write_driver( - do_write, - data, - col, - (*path).pt_addr_spec, - strlen((*path).pt_addr_spec), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b">\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} diff --git a/mmime/src/mailmime/content.rs b/mmime/src/mailmime/content.rs deleted file mode 100644 index c41ec180f..000000000 --- a/mmime/src/mailmime/content.rs +++ /dev/null @@ -1,2357 +0,0 @@ -use crate::clist::*; -use crate::mailimf::types::*; -use crate::mailimf::*; -use crate::mailmime::types::*; -use crate::mailmime::types_helper::*; -use crate::mailmime::*; -use crate::mmapstring::*; -use crate::other::*; - -pub const MAILMIME_DEFAULT_TYPE_TEXT_PLAIN: libc::c_uint = 0; -pub const MULTIPART_NEXT_STATE_2: libc::c_uint = 2; -pub const MULTIPART_NEXT_STATE_1: libc::c_uint = 1; -pub const MULTIPART_NEXT_STATE_0: libc::c_uint = 0; -pub const MULTIPART_CLOSE_STATE_4: libc::c_uint = 4; -pub const MULTIPART_CLOSE_STATE_3: libc::c_uint = 3; -pub const MULTIPART_CLOSE_STATE_2: libc::c_uint = 2; -pub const MULTIPART_CLOSE_STATE_1: libc::c_uint = 1; -pub const MULTIPART_CLOSE_STATE_0: libc::c_uint = 0; -pub const BODY_PART_DASH2_STATE_0: libc::c_uint = 0; -pub const BODY_PART_DASH2_STATE_6: libc::c_uint = 6; -pub const BODY_PART_DASH2_STATE_5: libc::c_uint = 5; -pub const BODY_PART_DASH2_STATE_4: libc::c_uint = 4; -pub const BODY_PART_DASH2_STATE_2: libc::c_uint = 2; -pub const BODY_PART_DASH2_STATE_1: libc::c_uint = 1; -pub const BODY_PART_DASH2_STATE_3: libc::c_uint = 3; -pub const PREAMBLE_STATE_A: libc::c_uint = 1; -pub const PREAMBLE_STATE_E: libc::c_uint = 6; -pub const PREAMBLE_STATE_D: libc::c_uint = 5; -pub const PREAMBLE_STATE_A0: libc::c_uint = 0; -pub const PREAMBLE_STATE_C: libc::c_uint = 4; -pub const PREAMBLE_STATE_B: libc::c_uint = 3; -pub const PREAMBLE_STATE_A1: libc::c_uint = 2; -pub const MAILMIME_DEFAULT_TYPE_MESSAGE: libc::c_uint = 1; -pub const STATE_NORMAL: libc::c_uint = 0; -pub const STATE_CR: libc::c_uint = 3; -pub const STATE_CODED: libc::c_uint = 1; -pub const STATE_OUT: libc::c_uint = 2; - -pub unsafe fn mailmime_content_charset_get( - mut content: *mut mailmime_content, -) -> *mut libc::c_char { - let mut charset: *mut libc::c_char = 0 as *mut libc::c_char; - charset = mailmime_content_param_get( - content, - b"charset\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - ); - if charset.is_null() { - return b"us-ascii\x00" as *const u8 as *const libc::c_char as *mut libc::c_char; - } else { - return charset; - }; -} - -pub unsafe fn mailmime_content_param_get( - mut content: *mut mailmime_content, - mut name: *mut libc::c_char, -) -> *mut libc::c_char { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*content).ct_parameters).first; - while !cur.is_null() { - let mut param: *mut mailmime_parameter = 0 as *mut mailmime_parameter; - param = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailmime_parameter; - if strcasecmp((*param).pa_name, name) == 0i32 { - return (*param).pa_value; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - return 0 as *mut libc::c_char; -} - -pub unsafe fn mailmime_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut Mailmime, -) -> libc::c_int { - let mut mime: *mut Mailmime = 0 as *mut Mailmime; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut content_message: *mut mailmime_content = 0 as *mut mailmime_content; - let mut cur_token: size_t = 0; - let mut mime_fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - let mut data_str: *const libc::c_char = 0 as *const libc::c_char; - let mut data_size: size_t = 0; - let mut bp_token: size_t = 0; - cur_token = *indx; - content_message = mailmime_get_content_message(); - if content_message.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - mime_fields = mailmime_fields_new_empty(); - if mime_fields.is_null() { - mailmime_content_free(content_message); - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - data_str = message.offset(cur_token as isize); - data_size = length.wrapping_sub(cur_token); - bp_token = 0i32 as size_t; - r = mailmime_parse_with_default( - data_str, - data_size, - &mut bp_token, - MAILMIME_DEFAULT_TYPE_TEXT_PLAIN as libc::c_int, - content_message, - mime_fields, - &mut mime, - ); - cur_token = (cur_token as libc::size_t).wrapping_add(bp_token) as size_t as size_t; - if r != MAILIMF_NO_ERROR as libc::c_int { - mailmime_fields_free(mime_fields); - res = r; - mailmime_fields_free(mime_fields); - } else { - *indx = cur_token; - *result = mime; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - return res; -} -/* - * libEtPan! -- a mail stuff library - * - * Copyright (C) 2001, 2005 - DINH Viet Hoa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the libEtPan! project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * $Id: mailmime_content.c,v 1.47 2011/06/28 22:13:36 hoa Exp $ - */ -/* - RFC 2045 - RFC 2046 - RFC 2047 - - RFC 2231 -*/ -unsafe fn mailmime_parse_with_default( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut default_type: libc::c_int, - mut content_type: *mut mailmime_content, - mut mime_fields: *mut mailmime_fields, - mut result: *mut *mut Mailmime, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut body_type: libc::c_int = 0; - let mut encoding: libc::c_int = 0; - let mut body: *mut mailmime_data = 0 as *mut mailmime_data; - let mut boundary: *mut libc::c_char = 0 as *mut libc::c_char; - let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; - let mut list: *mut clist = 0 as *mut clist; - let mut msg_mime: *mut Mailmime = 0 as *mut Mailmime; - let mut mime: *mut Mailmime = 0 as *mut Mailmime; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut preamble: *mut mailmime_data = 0 as *mut mailmime_data; - let mut epilogue: *mut mailmime_data = 0 as *mut mailmime_data; - preamble = 0 as *mut mailmime_data; - epilogue = 0 as *mut mailmime_data; - cur_token = *indx; - if content_type.is_null() { - if !mime_fields.is_null() { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*mime_fields).fld_list).first; - while !cur.is_null() { - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - field = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailmime_field; - if (*field).fld_type == MAILMIME_FIELD_TYPE as libc::c_int { - content_type = (*field).fld_data.fld_content; - (*field).fld_data.fld_content = 0 as *mut mailmime_content; - clist_delete((*mime_fields).fld_list, cur); - mailmime_field_free(field); - /* - there may be a leak due to the detached content type - in case the function fails - */ - break; - } else { - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - } - } - } - /* set default type if no content type */ - if content_type.is_null() { - /* content_type is detached, in any case, we will have to free it */ - if default_type == MAILMIME_DEFAULT_TYPE_TEXT_PLAIN as libc::c_int { - content_type = mailmime_get_content_text(); - if content_type.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 16594950150283576116; - } else { - current_block = 7828949454673616476; - } - } else { - /* message */ - body_type = MAILMIME_MESSAGE as libc::c_int; - content_type = mailmime_get_content_message(); - if content_type.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 16594950150283576116; - } else { - current_block = 7828949454673616476; - } - } - } else { - current_block = 7828949454673616476; - } - match current_block { - 7828949454673616476 => { - boundary = 0 as *mut libc::c_char; - match (*(*content_type).ct_type).tp_type { - 2 => match (*(*(*content_type).ct_type).tp_data.tp_composite_type).ct_type { - 2 => { - boundary = mailmime_extract_boundary(content_type); - if boundary.is_null() { - body_type = MAILMIME_SINGLE as libc::c_int - } else { - body_type = MAILMIME_MULTIPLE as libc::c_int - } - current_block = 11793792312832361944; - } - 1 => { - if strcasecmp( - (*content_type).ct_subtype, - b"rfc822\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - body_type = MAILMIME_MESSAGE as libc::c_int - } else { - body_type = MAILMIME_SINGLE as libc::c_int - } - current_block = 11793792312832361944; - } - _ => { - res = MAILIMF_ERROR_INVAL as libc::c_int; - current_block = 18099180955076792539; - } - }, - _ => { - body_type = MAILMIME_SINGLE as libc::c_int; - current_block = 11793792312832361944; - } - } - match current_block { - 11793792312832361944 => { - if !mime_fields.is_null() { - encoding = mailmime_transfer_encoding_get(mime_fields) - } else { - encoding = MAILMIME_MECHANISM_8BIT as libc::c_int - } - if body_type == MAILMIME_MESSAGE as libc::c_int { - match encoding { - 4 | 5 => body_type = MAILMIME_SINGLE as libc::c_int, - _ => {} - } - } - cur_token = *indx; - body = mailmime_data_new( - MAILMIME_DATA_TEXT as libc::c_int, - encoding, - 1i32, - message.offset(cur_token as isize), - length.wrapping_sub(cur_token), - 0 as *mut libc::c_char, - ); - if body.is_null() { - free(boundary as *mut libc::c_void); - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - list = 0 as *mut clist; - msg_mime = 0 as *mut Mailmime; - fields = 0 as *mut mailimf_fields; - match body_type { - 3 => { - let mut submime_fields: *mut mailmime_fields = - 0 as *mut mailmime_fields; - r = mailimf_envelope_and_optional_fields_parse( - message, - length, - &mut cur_token, - &mut fields, - ); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - res = r; - current_block = 18099180955076792539; - } else { - r = mailimf_crlf_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - mailimf_fields_free(fields); - res = r; - current_block = 18099180955076792539; - } else { - submime_fields = 0 as *mut mailmime_fields; - r = mailmime_fields_parse(fields, &mut submime_fields); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - mailimf_fields_free(fields); - res = r; - current_block = 18099180955076792539; - } else { - remove_unparsed_mime_headers(fields); - r = mailmime_parse_with_default( - message, - length, - &mut cur_token, - MAILMIME_DEFAULT_TYPE_TEXT_PLAIN as libc::c_int, - 0 as *mut mailmime_content, - submime_fields, - &mut msg_mime, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - current_block = 12065775993741208975; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - mailmime_fields_free(mime_fields); - msg_mime = 0 as *mut Mailmime; - current_block = 12065775993741208975; - } else { - mailmime_fields_free(mime_fields); - res = r; - current_block = 18099180955076792539; - } - } - } - } - } - 2 => { - let mut default_subtype: libc::c_int = 0; - default_subtype = MAILMIME_DEFAULT_TYPE_TEXT_PLAIN as libc::c_int; - if !content_type.is_null() { - if strcasecmp( - (*content_type).ct_subtype, - b"digest\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - default_subtype = - MAILMIME_DEFAULT_TYPE_MESSAGE as libc::c_int - } - } - cur_token = *indx; - r = mailmime_multipart_body_parse( - message, - length, - &mut cur_token, - boundary, - default_subtype, - &mut list, - &mut preamble, - &mut epilogue, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - current_block = 4804377075063615140; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 18099180955076792539; - } else { - current_block = 4804377075063615140; - } - } else { - res = r; - current_block = 18099180955076792539; - } - match current_block { - 18099180955076792539 => {} - _ => { - free(boundary as *mut libc::c_void); - current_block = 12065775993741208975; - } - } - } - _ => { - /* do nothing */ - current_block = 12065775993741208975; - } - } - match current_block { - 18099180955076792539 => {} - _ => { - mime = mailmime_new( - body_type, - message, - length, - mime_fields, - content_type, - body, - preamble, - epilogue, - list, - fields, - msg_mime, - ); - /* preamble */ - /* epilogue */ - if mime.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !epilogue.is_null() { - mailmime_data_free(epilogue); - } - if !preamble.is_null() { - mailmime_data_free(preamble); - } - if !msg_mime.is_null() { - mailmime_free(msg_mime); - } - if !list.is_null() { - clist_foreach( - list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some( - mailmime_free, - )), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - } else { - *result = mime; - *indx = length; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - } - _ => {} - } - mailmime_content_free(content_type); - } - _ => {} - } - return res; -} -unsafe fn mailmime_multipart_body_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut boundary: *mut libc::c_char, - mut default_subtype: libc::c_int, - mut result: *mut *mut clist, - mut p_preamble: *mut *mut mailmime_data, - mut p_epilogue: *mut *mut mailmime_data, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut list: *mut clist = 0 as *mut clist; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut preamble_begin: size_t = 0; - let mut preamble_length: size_t = 0; - let mut preamble_end: size_t = 0; - let mut epilogue_begin: size_t = 0; - let mut epilogue_length: size_t = 0; - let mut preamble: *mut mailmime_data = 0 as *mut mailmime_data; - let mut epilogue: *mut mailmime_data = 0 as *mut mailmime_data; - let mut part_begin: size_t = 0; - let mut final_part: libc::c_int = 0; - preamble = 0 as *mut mailmime_data; - epilogue = 0 as *mut mailmime_data; - cur_token = *indx; - preamble_begin = cur_token; - preamble_end = preamble_begin; - r = mailmime_preamble_parse(message, length, &mut cur_token, 1i32); - if r == MAILIMF_NO_ERROR as libc::c_int { - loop { - preamble_end = cur_token; - r = mailmime_boundary_parse(message, length, &mut cur_token, boundary); - if r == MAILIMF_NO_ERROR as libc::c_int { - current_block = 16924917904204750491; - break; - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailmime_preamble_parse(message, length, &mut cur_token, 0i32); - if r == MAILIMF_NO_ERROR as libc::c_int { - continue; - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 16924917904204750491; - break; - } - res = r; - current_block = 13657460241182544761; - break; - } else { - /* do nothing */ - res = r; - current_block = 13657460241182544761; - break; - } - } - } else { - current_block = 16924917904204750491; - } - match current_block { - 16924917904204750491 => { - preamble_end = (preamble_end as libc::size_t).wrapping_sub(2i32 as libc::size_t) - as size_t as size_t; - if preamble_end != preamble_begin { - if *message.offset(preamble_end.wrapping_sub(1i32 as libc::size_t) as isize) - as libc::c_int - == '\n' as i32 - { - preamble_end = preamble_end.wrapping_sub(1); - if preamble_end.wrapping_sub(1i32 as libc::size_t) >= preamble_begin { - if *message.offset(preamble_end.wrapping_sub(1i32 as libc::size_t) as isize) - as libc::c_int - == '\r' as i32 - { - preamble_end = preamble_end.wrapping_sub(1) - } - } - } else if *message.offset(preamble_end.wrapping_sub(1i32 as libc::size_t) as isize) - as libc::c_int - == '\r' as i32 - { - preamble_end = preamble_end.wrapping_sub(1) - } - } - preamble_length = preamble_end.wrapping_sub(preamble_begin); - part_begin = cur_token; - loop { - r = mailmime_lwsp_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r; - current_block = 13657460241182544761; - break; - } else { - r = mailimf_crlf_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - part_begin = cur_token - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - /* do nothing */ - current_block = 9353995356876505083; - break; - } else { - res = r; - current_block = 13657460241182544761; - break; - } - } - } - match current_block { - 13657460241182544761 => {} - _ => { - cur_token = part_begin; - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - final_part = 0i32; - loop { - if !(0 == final_part) { - current_block = 15447629348493591490; - break; - } - let mut bp_token: size_t = 0; - let mut mime_bp: *mut Mailmime = 0 as *mut Mailmime; - let mut data_str: *const libc::c_char = 0 as *const libc::c_char; - let mut data_size: size_t = 0; - let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; - let mut mime_fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - r = mailmime_body_part_dash2_transport_crlf_parse( - message, - length, - &mut cur_token, - boundary, - &mut data_str, - &mut data_size, - ); - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailmime_body_part_dash2_close_parse( - message, - length, - &mut cur_token, - boundary, - &mut data_str, - &mut data_size, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - final_part = 1i32 - } - } - if r == MAILIMF_NO_ERROR as libc::c_int { - bp_token = 0i32 as size_t; - r = mailimf_optional_fields_parse( - data_str, - data_size, - &mut bp_token, - &mut fields, - ); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - res = r; - current_block = 6612762688763383599; - break; - } else { - r = mailimf_crlf_parse(data_str, data_size, &mut bp_token); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - mailimf_fields_free(fields); - res = r; - current_block = 6612762688763383599; - break; - } else { - mime_fields = 0 as *mut mailmime_fields; - r = mailmime_fields_parse(fields, &mut mime_fields); - mailimf_fields_free(fields); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - res = r; - current_block = 6612762688763383599; - break; - } else { - r = mailmime_parse_with_default( - data_str, - data_size, - &mut bp_token, - default_subtype, - 0 as *mut mailmime_content, - mime_fields, - &mut mime_bp, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - r = clist_insert_after( - list, - (*list).last, - mime_bp as *mut libc::c_void, - ); - if r < 0i32 { - mailmime_free(mime_bp); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 6612762688763383599; - break; - } else { - r = mailmime_multipart_next_parse( - message, - length, - &mut cur_token, - ); - r == MAILIMF_NO_ERROR as libc::c_int; - } - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - mailmime_fields_free(mime_fields); - current_block = 15447629348493591490; - break; - } else { - mailmime_fields_free(mime_fields); - res = r; - current_block = 6612762688763383599; - break; - } - } - } - } - } else { - /* do nothing */ - res = r; - current_block = 6612762688763383599; - break; - } - } - match current_block { - 15447629348493591490 => { - epilogue_begin = length; - /* parse transport-padding */ - loop { - r = mailmime_lwsp_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - res = r; - current_block = 6612762688763383599; - break; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 13201766686570145889; - break; - } - } - match current_block { - 6612762688763383599 => {} - _ => { - r = mailimf_crlf_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - epilogue_begin = cur_token; - current_block = 1739363794695357236; - } else if r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r; - current_block = 6612762688763383599; - } else { - current_block = 1739363794695357236; - } - match current_block { - 6612762688763383599 => {} - _ => { - epilogue_length = - length.wrapping_sub(epilogue_begin); - if preamble_length != 0i32 as libc::size_t { - preamble = mailmime_data_new( - MAILMIME_DATA_TEXT as libc::c_int, - MAILMIME_MECHANISM_8BIT as libc::c_int, - 1i32, - message.offset(preamble_begin as isize), - preamble_length, - 0 as *mut libc::c_char, - ); - if preamble.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 6612762688763383599; - } else { - current_block = 5636883459695696059; - } - } else { - current_block = 5636883459695696059; - } - match current_block { - 6612762688763383599 => {} - _ => { - if epilogue_length != 0i32 as libc::size_t { - epilogue = mailmime_data_new( - MAILMIME_DATA_TEXT as libc::c_int, - MAILMIME_MECHANISM_8BIT - as libc::c_int, - 1i32, - message.offset( - epilogue_begin as isize, - ), - epilogue_length, - 0 as *mut libc::c_char, - ); - if epilogue.is_null() { - res = MAILIMF_ERROR_MEMORY - as libc::c_int; - current_block = 6612762688763383599; - } else { - current_block = 7337917895049117968; - } - } else { - current_block = 7337917895049117968; - } - match current_block { - 6612762688763383599 => {} - _ => { - cur_token = length; - *result = list; - *p_preamble = preamble; - *p_epilogue = epilogue; - *indx = cur_token; - return MAILIMF_NO_ERROR - as libc::c_int; - } - } - } - } - } - } - } - } - } - _ => {} - } - if !epilogue.is_null() { - mailmime_data_free(epilogue); - } - if !preamble.is_null() { - mailmime_data_free(preamble); - } - clist_foreach( - list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailmime_free)), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - } - } - } - _ => {} - } - return res; -} -unsafe fn mailmime_lwsp_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - cur_token = *indx; - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - while 0 != is_wsp(*message.offset(cur_token as isize)) { - cur_token = cur_token.wrapping_add(1); - if cur_token >= length { - break; - } - } - if cur_token == *indx { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn is_wsp(mut ch: libc::c_char) -> libc::c_int { - if ch as libc::c_int == ' ' as i32 || ch as libc::c_int == '\t' as i32 { - return 1i32; - } - return 0i32; -} - -pub unsafe fn mailmime_multipart_next_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut state: libc::c_int = 0; - let mut cur_token: size_t = 0; - cur_token = *indx; - state = MULTIPART_NEXT_STATE_0 as libc::c_int; - while state != MULTIPART_NEXT_STATE_2 as libc::c_int { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match state { - 0 => match *message.offset(cur_token as isize) as libc::c_int { - 32 => state = MULTIPART_NEXT_STATE_0 as libc::c_int, - 9 => state = MULTIPART_NEXT_STATE_0 as libc::c_int, - 13 => state = MULTIPART_NEXT_STATE_1 as libc::c_int, - 10 => state = MULTIPART_NEXT_STATE_2 as libc::c_int, - _ => return MAILIMF_ERROR_PARSE as libc::c_int, - }, - 1 => match *message.offset(cur_token as isize) as libc::c_int { - 10 => state = MULTIPART_NEXT_STATE_2 as libc::c_int, - _ => return MAILIMF_ERROR_PARSE as libc::c_int, - }, - _ => {} - } - cur_token = cur_token.wrapping_add(1) - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_body_part_dash2_close_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut boundary: *mut libc::c_char, - mut result: *mut *const libc::c_char, - mut result_size: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut data_str: *const libc::c_char = 0 as *const libc::c_char; - let mut data_size: size_t = 0; - let mut begin_text: *const libc::c_char = 0 as *const libc::c_char; - let mut end_text: *const libc::c_char = 0 as *const libc::c_char; - cur_token = *indx; - begin_text = message.offset(cur_token as isize); - end_text = message.offset(cur_token as isize); - loop { - r = mailmime_body_part_dash2_parse( - message, - length, - &mut cur_token, - boundary, - &mut data_str, - &mut data_size, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - end_text = data_str.offset(data_size as isize) - } else { - return r; - } - /* - There's no MIME multipart close bounary. - Ignore the issue and succeed. - https://github.com/MailCore/mailcore2/issues/122 - */ - if cur_token >= length { - break; - } - r = mailmime_multipart_close_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - break; - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - } else { - return r; - } - } - *indx = cur_token; - *result = begin_text; - *result_size = end_text.wrapping_offset_from(begin_text) as size_t; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_multipart_close_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, -) -> libc::c_int { - let mut state: libc::c_int = 0; - let mut cur_token: size_t = 0; - cur_token = *indx; - state = MULTIPART_CLOSE_STATE_0 as libc::c_int; - while state != MULTIPART_CLOSE_STATE_4 as libc::c_int { - match state { - 0 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match *message.offset(cur_token as isize) as libc::c_int { - 45 => state = MULTIPART_CLOSE_STATE_1 as libc::c_int, - _ => return MAILIMF_ERROR_PARSE as libc::c_int, - } - } - 1 => { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match *message.offset(cur_token as isize) as libc::c_int { - 45 => state = MULTIPART_CLOSE_STATE_2 as libc::c_int, - _ => return MAILIMF_ERROR_PARSE as libc::c_int, - } - } - 2 => { - if cur_token >= length { - state = MULTIPART_CLOSE_STATE_4 as libc::c_int - } else { - match *message.offset(cur_token as isize) as libc::c_int { - 32 => state = MULTIPART_CLOSE_STATE_2 as libc::c_int, - 9 => state = MULTIPART_CLOSE_STATE_2 as libc::c_int, - 13 => state = MULTIPART_CLOSE_STATE_3 as libc::c_int, - 10 => state = MULTIPART_CLOSE_STATE_4 as libc::c_int, - _ => state = MULTIPART_CLOSE_STATE_4 as libc::c_int, - } - } - } - 3 => { - if cur_token >= length { - state = MULTIPART_CLOSE_STATE_4 as libc::c_int - } else { - match *message.offset(cur_token as isize) as libc::c_int { - 10 => state = MULTIPART_CLOSE_STATE_4 as libc::c_int, - _ => state = MULTIPART_CLOSE_STATE_4 as libc::c_int, - } - } - } - _ => {} - } - cur_token = cur_token.wrapping_add(1) - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_body_part_dash2_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut boundary: *mut libc::c_char, - mut result: *mut *const libc::c_char, - mut result_size: *mut size_t, -) -> libc::c_int { - let mut state: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut size: size_t = 0; - let mut begin_text: size_t = 0; - let mut end_text: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - state = BODY_PART_DASH2_STATE_0 as libc::c_int; - begin_text = cur_token; - end_text = length; - while state != BODY_PART_DASH2_STATE_5 as libc::c_int { - if cur_token >= length { - break; - } - match state { - 0 => match *message.offset(cur_token as isize) as libc::c_int { - 13 => state = BODY_PART_DASH2_STATE_1 as libc::c_int, - 10 => state = BODY_PART_DASH2_STATE_2 as libc::c_int, - _ => state = BODY_PART_DASH2_STATE_0 as libc::c_int, - }, - 1 => match *message.offset(cur_token as isize) as libc::c_int { - 10 => state = BODY_PART_DASH2_STATE_2 as libc::c_int, - _ => state = BODY_PART_DASH2_STATE_0 as libc::c_int, - }, - 2 => match *message.offset(cur_token as isize) as libc::c_int { - 45 => { - end_text = cur_token; - state = BODY_PART_DASH2_STATE_3 as libc::c_int - } - 13 => state = BODY_PART_DASH2_STATE_1 as libc::c_int, - 10 => state = BODY_PART_DASH2_STATE_2 as libc::c_int, - _ => state = BODY_PART_DASH2_STATE_0 as libc::c_int, - }, - 3 => match *message.offset(cur_token as isize) as libc::c_int { - 13 => state = BODY_PART_DASH2_STATE_1 as libc::c_int, - 10 => state = BODY_PART_DASH2_STATE_2 as libc::c_int, - 45 => state = BODY_PART_DASH2_STATE_4 as libc::c_int, - _ => state = BODY_PART_DASH2_STATE_0 as libc::c_int, - }, - 4 => { - r = mailmime_boundary_parse(message, length, &mut cur_token, boundary); - if r == MAILIMF_NO_ERROR as libc::c_int { - state = BODY_PART_DASH2_STATE_5 as libc::c_int - } else { - state = BODY_PART_DASH2_STATE_6 as libc::c_int - } - } - _ => {} - } - if state != BODY_PART_DASH2_STATE_5 as libc::c_int - && state != BODY_PART_DASH2_STATE_6 as libc::c_int - { - cur_token = cur_token.wrapping_add(1) - } - if state == BODY_PART_DASH2_STATE_6 as libc::c_int { - state = BODY_PART_DASH2_STATE_0 as libc::c_int - } - } - size = end_text.wrapping_sub(begin_text); - if size >= 1i32 as libc::size_t { - if *message.offset(end_text.wrapping_sub(1i32 as libc::size_t) as isize) as libc::c_int - == '\r' as i32 - { - end_text = end_text.wrapping_sub(1); - size = size.wrapping_sub(1) - } else if size >= 1i32 as libc::size_t { - if *message.offset(end_text.wrapping_sub(1i32 as libc::size_t) as isize) as libc::c_int - == '\n' as i32 - { - end_text = end_text.wrapping_sub(1); - size = size.wrapping_sub(1); - if size >= 1i32 as libc::size_t { - if *message.offset(end_text.wrapping_sub(1i32 as libc::size_t) as isize) - as libc::c_int - == '\r' as i32 - { - end_text = end_text.wrapping_sub(1); - size = size.wrapping_sub(1) - } - } - } - } - } - size = end_text.wrapping_sub(begin_text); - if size == 0i32 as libc::size_t { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - *result = message.offset(begin_text as isize); - *result_size = size; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_boundary_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut boundary: *mut libc::c_char, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut len: size_t = 0; - cur_token = *indx; - len = strlen(boundary); - if cur_token.wrapping_add(len) >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - if strncmp(message.offset(cur_token as isize), boundary, len) != 0i32 { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - cur_token = (cur_token as libc::size_t).wrapping_add(len) as size_t as size_t; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_body_part_dash2_transport_crlf_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut boundary: *mut libc::c_char, - mut result: *mut *const libc::c_char, - mut result_size: *mut size_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut data_str: *const libc::c_char = 0 as *const libc::c_char; - let mut data_size: size_t = 0; - let mut begin_text: *const libc::c_char = 0 as *const libc::c_char; - let mut end_text: *const libc::c_char = 0 as *const libc::c_char; - cur_token = *indx; - begin_text = message.offset(cur_token as isize); - end_text = message.offset(cur_token as isize); - loop { - r = mailmime_body_part_dash2_parse( - message, - length, - &mut cur_token, - boundary, - &mut data_str, - &mut data_size, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - end_text = data_str.offset(data_size as isize) - } else { - return r; - } - loop { - r = mailmime_lwsp_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - continue; - } - /* do nothing */ - if r == MAILIMF_ERROR_PARSE as libc::c_int { - break; - } - return r; - } - r = mailimf_crlf_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - break; - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - } else { - return r; - } - } - *indx = cur_token; - *result = begin_text; - *result_size = end_text.wrapping_offset_from(begin_text) as size_t; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_preamble_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut beol: libc::c_int, -) -> libc::c_int { - let mut state: libc::c_int = 0; - let mut cur_token: size_t = 0; - cur_token = *indx; - if 0 != beol { - state = PREAMBLE_STATE_A0 as libc::c_int - } else { - state = PREAMBLE_STATE_A as libc::c_int - } - while state != PREAMBLE_STATE_E as libc::c_int { - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match state { - 0 => match *message.offset(cur_token as isize) as libc::c_int { - 45 => state = PREAMBLE_STATE_A1 as libc::c_int, - 13 => state = PREAMBLE_STATE_B as libc::c_int, - 10 => state = PREAMBLE_STATE_C as libc::c_int, - _ => state = PREAMBLE_STATE_A as libc::c_int, - }, - 1 => match *message.offset(cur_token as isize) as libc::c_int { - 13 => state = PREAMBLE_STATE_B as libc::c_int, - 10 => state = PREAMBLE_STATE_C as libc::c_int, - _ => state = PREAMBLE_STATE_A as libc::c_int, - }, - 2 => match *message.offset(cur_token as isize) as libc::c_int { - 45 => state = PREAMBLE_STATE_E as libc::c_int, - 13 => state = PREAMBLE_STATE_B as libc::c_int, - 10 => state = PREAMBLE_STATE_C as libc::c_int, - _ => state = PREAMBLE_STATE_A as libc::c_int, - }, - 3 => match *message.offset(cur_token as isize) as libc::c_int { - 13 => state = PREAMBLE_STATE_B as libc::c_int, - 10 => state = PREAMBLE_STATE_C as libc::c_int, - 45 => state = PREAMBLE_STATE_D as libc::c_int, - _ => state = PREAMBLE_STATE_A0 as libc::c_int, - }, - 4 => match *message.offset(cur_token as isize) as libc::c_int { - 45 => state = PREAMBLE_STATE_D as libc::c_int, - 13 => state = PREAMBLE_STATE_B as libc::c_int, - 10 => state = PREAMBLE_STATE_C as libc::c_int, - _ => state = PREAMBLE_STATE_A0 as libc::c_int, - }, - 5 => match *message.offset(cur_token as isize) as libc::c_int { - 45 => state = PREAMBLE_STATE_E as libc::c_int, - _ => state = PREAMBLE_STATE_A as libc::c_int, - }, - _ => {} - } - cur_token = cur_token.wrapping_add(1) - } - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn remove_unparsed_mime_headers(mut fields: *mut mailimf_fields) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*fields).fld_list).first; - while !cur.is_null() { - let mut field: *mut mailimf_field = 0 as *mut mailimf_field; - let mut delete: libc::c_int = 0; - field = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailimf_field; - match (*field).fld_type { - 22 => { - delete = 0i32; - if strncasecmp( - (*(*field).fld_data.fld_optional_field).fld_name, - b"Content-\x00" as *const u8 as *const libc::c_char, - 8i32 as libc::size_t, - ) == 0i32 - { - let mut name: *mut libc::c_char = 0 as *mut libc::c_char; - name = (*(*field).fld_data.fld_optional_field) - .fld_name - .offset(8isize); - if strcasecmp(name, b"Type\x00" as *const u8 as *const libc::c_char) == 0i32 - || strcasecmp( - name, - b"Transfer-Encoding\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - || strcasecmp(name, b"ID\x00" as *const u8 as *const libc::c_char) == 0i32 - || strcasecmp(name, b"Description\x00" as *const u8 as *const libc::c_char) - == 0i32 - || strcasecmp(name, b"Disposition\x00" as *const u8 as *const libc::c_char) - == 0i32 - || strcasecmp(name, b"Language\x00" as *const u8 as *const libc::c_char) - == 0i32 - { - delete = 1i32 - } - } else if strcasecmp( - (*(*field).fld_data.fld_optional_field).fld_name, - b"MIME-Version\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - delete = 1i32 - } - if 0 != delete { - cur = clist_delete((*fields).fld_list, cur); - mailimf_field_free(field); - } else { - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - } - _ => { - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - } - } -} - -pub unsafe fn mailmime_extract_boundary( - mut content_type: *mut mailmime_content, -) -> *mut libc::c_char { - let mut boundary: *mut libc::c_char = 0 as *mut libc::c_char; - boundary = mailmime_content_param_get( - content_type, - b"boundary\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - ); - if !boundary.is_null() { - let mut len: size_t = 0; - let mut new_boundary: *mut libc::c_char = 0 as *mut libc::c_char; - len = strlen(boundary); - new_boundary = malloc(len.wrapping_add(1i32 as libc::size_t)) as *mut libc::c_char; - if new_boundary.is_null() { - return 0 as *mut libc::c_char; - } - if *boundary.offset(0isize) as libc::c_int == '\"' as i32 { - strncpy( - new_boundary, - boundary.offset(1isize), - len.wrapping_sub(2i32 as libc::size_t), - ); - *new_boundary.offset(len.wrapping_sub(2i32 as libc::size_t) as isize) = - 0i32 as libc::c_char - } else { - strcpy(new_boundary, boundary); - } - boundary = new_boundary - } - return boundary; -} - -pub unsafe fn mailmime_get_section( - mut mime: *mut Mailmime, - mut section: *mut mailmime_section, - mut result: *mut *mut Mailmime, -) -> libc::c_int { - return mailmime_get_section_list(mime, (*(*section).sec_list).first, result); -} -unsafe fn mailmime_get_section_list( - mut mime: *mut Mailmime, - mut list: *mut clistiter, - mut result: *mut *mut Mailmime, -) -> libc::c_int { - let mut id: uint32_t = 0; - let mut data: *mut Mailmime = 0 as *mut Mailmime; - let mut submime: *mut Mailmime = 0 as *mut Mailmime; - if list.is_null() { - *result = mime; - return MAILIMF_NO_ERROR as libc::c_int; - } - id = *((if !list.is_null() { - (*list).data - } else { - 0 as *mut libc::c_void - }) as *mut uint32_t); - data = 0 as *mut Mailmime; - match (*mime).mm_type { - 1 => return MAILIMF_ERROR_INVAL as libc::c_int, - 2 => { - data = clist_nth_data( - (*mime).mm_data.mm_multipart.mm_mp_list, - id.wrapping_sub(1i32 as libc::c_uint) as libc::c_int, - ) as *mut Mailmime; - if data.is_null() { - return MAILIMF_ERROR_INVAL as libc::c_int; - } - if !if !list.is_null() { - (*list).next - } else { - 0 as *mut clistcell - } - .is_null() - { - return mailmime_get_section_list( - data, - if !list.is_null() { - (*list).next - } else { - 0 as *mut clistcell - }, - result, - ); - } else { - *result = data; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - 3 => { - submime = (*mime).mm_data.mm_message.mm_msg_mime; - match (*submime).mm_type { - 2 => { - data = clist_nth_data( - (*submime).mm_data.mm_multipart.mm_mp_list, - id.wrapping_sub(1i32 as libc::c_uint) as libc::c_int, - ) as *mut Mailmime; - if data.is_null() { - return MAILIMF_ERROR_INVAL as libc::c_int; - } - return mailmime_get_section_list( - data, - if !list.is_null() { - (*list).next - } else { - 0 as *mut clistcell - }, - result, - ); - } - _ => { - if id != 1i32 as libc::c_uint { - return MAILIMF_ERROR_INVAL as libc::c_int; - } - data = submime; - if data.is_null() { - return MAILIMF_ERROR_INVAL as libc::c_int; - } - return mailmime_get_section_list( - data, - if !list.is_null() { - (*list).next - } else { - 0 as *mut clistcell - }, - result, - ); - } - } - } - _ => return MAILIMF_ERROR_INVAL as libc::c_int, - }; -} -/* decode */ -pub unsafe fn mailmime_base64_body_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, - mut result_len: *mut size_t, -) -> libc::c_int { - return mailmime_base64_body_parse_impl(message, length, indx, result, result_len, 0i32); -} -unsafe fn mailmime_base64_body_parse_impl( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, - mut result_len: *mut size_t, - mut partial: libc::c_int, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut last_full_token_end: size_t = 0; - let mut chunk: [libc::c_char; 4] = [0; 4]; - let mut chunk_index: libc::c_int = 0; - let mut out: [libc::c_char; 3] = [0; 3]; - let mut mmapstr: *mut MMAPString = 0 as *mut MMAPString; - let mut res: libc::c_int = 0; - let mut r: libc::c_int = 0; - let mut written: size_t = 0; - chunk[0usize] = 0i32 as libc::c_char; - chunk[1usize] = 0i32 as libc::c_char; - chunk[2usize] = 0i32 as libc::c_char; - chunk[3usize] = 0i32 as libc::c_char; - cur_token = *indx; - last_full_token_end = *indx; - chunk_index = 0i32; - written = 0i32 as size_t; - mmapstr = mmap_string_sized_new( - length - .wrapping_sub(cur_token) - .wrapping_mul(3i32 as libc::size_t) - .wrapping_div(4i32 as libc::size_t), - ); - if mmapstr.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - loop { - let mut value: libc::c_schar = 0; - value = -1i32 as libc::c_schar; - while value as libc::c_int == -1i32 { - if cur_token >= length { - break; - } - value = get_base64_value(*message.offset(cur_token as isize)); - cur_token = cur_token.wrapping_add(1) - } - if value as libc::c_int == -1i32 { - current_block = 8845338526596852646; - break; - } - chunk[chunk_index as usize] = value as libc::c_char; - chunk_index += 1; - if !(chunk_index == 4i32) { - continue; - } - out[0usize] = ((chunk[0usize] as libc::c_int) << 2i32 - | chunk[1usize] as libc::c_int >> 4i32) as libc::c_char; - out[1usize] = ((chunk[1usize] as libc::c_int) << 4i32 - | chunk[2usize] as libc::c_int >> 2i32) as libc::c_char; - out[2usize] = ((chunk[2usize] as libc::c_int) << 6i32 | chunk[3usize] as libc::c_int) - as libc::c_char; - chunk[0usize] = 0i32 as libc::c_char; - chunk[1usize] = 0i32 as libc::c_char; - chunk[2usize] = 0i32 as libc::c_char; - chunk[3usize] = 0i32 as libc::c_char; - chunk_index = 0i32; - last_full_token_end = cur_token; - if mmap_string_append_len(mmapstr, out.as_mut_ptr(), 3i32 as size_t).is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 11891829943175634231; - break; - } else { - written = - (written as libc::size_t).wrapping_add(3i32 as libc::size_t) as size_t as size_t - } - } - match current_block { - 8845338526596852646 => { - if chunk_index != 0i32 && 0 == partial { - let mut len: size_t = 0; - len = 0i32 as size_t; - out[0usize] = ((chunk[0usize] as libc::c_int) << 2i32 - | chunk[1usize] as libc::c_int >> 4i32) - as libc::c_char; - len = len.wrapping_add(1); - if chunk_index >= 3i32 { - out[1usize] = ((chunk[1usize] as libc::c_int) << 4i32 - | chunk[2usize] as libc::c_int >> 2i32) - as libc::c_char; - len = len.wrapping_add(1) - } - if mmap_string_append_len(mmapstr, out.as_mut_ptr(), len).is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 11891829943175634231; - } else { - written = (written as libc::size_t).wrapping_add(len) as size_t as size_t; - current_block = 16738040538446813684; - } - } else { - current_block = 16738040538446813684; - } - match current_block { - 11891829943175634231 => {} - _ => { - if 0 != partial { - cur_token = last_full_token_end - } - r = mmap_string_ref(mmapstr); - if r < 0i32 { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *indx = cur_token; - *result = (*mmapstr).str_0; - *result_len = written; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - _ => {} - } - mmap_string_free(mmapstr); - } - return res; -} -/* ************************************************************************* */ -/* MIME part decoding */ -unsafe fn get_base64_value(mut ch: libc::c_char) -> libc::c_schar { - if ch as libc::c_int >= 'A' as i32 && ch as libc::c_int <= 'Z' as i32 { - return (ch as libc::c_int - 'A' as i32) as libc::c_schar; - } - if ch as libc::c_int >= 'a' as i32 && ch as libc::c_int <= 'z' as i32 { - return (ch as libc::c_int - 'a' as i32 + 26i32) as libc::c_schar; - } - if ch as libc::c_int >= '0' as i32 && ch as libc::c_int <= '9' as i32 { - return (ch as libc::c_int - '0' as i32 + 52i32) as libc::c_schar; - } - match ch as libc::c_int { - 43 => return 62i32 as libc::c_schar, - 47 => return 63i32 as libc::c_schar, - 61 => return -1i32 as libc::c_schar, - _ => return -1i32 as libc::c_schar, - }; -} - -pub unsafe fn mailmime_quoted_printable_body_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, - mut result_len: *mut size_t, - mut in_header: libc::c_int, -) -> libc::c_int { - return mailmime_quoted_printable_body_parse_impl( - message, length, indx, result, result_len, in_header, 0i32, - ); -} -unsafe fn mailmime_quoted_printable_body_parse_impl( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, - mut result_len: *mut size_t, - mut in_header: libc::c_int, - mut partial: libc::c_int, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut state: libc::c_int = 0; - let mut r: libc::c_int = 0; - let mut ch: libc::c_char = 0; - let mut count: size_t = 0; - let mut start: *const libc::c_char = 0 as *const libc::c_char; - let mut mmapstr: *mut MMAPString = 0 as *mut MMAPString; - let mut res: libc::c_int = 0; - let mut written: size_t = 0; - state = STATE_NORMAL as libc::c_int; - cur_token = *indx; - count = 0i32 as size_t; - start = message.offset(cur_token as isize); - written = 0i32 as size_t; - mmapstr = mmap_string_sized_new(length.wrapping_sub(cur_token)); - if mmapstr.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - loop { - if !(state != STATE_OUT as libc::c_int) { - current_block = 12693738997172594219; - break; - } - if cur_token >= length { - state = STATE_OUT as libc::c_int; - if 0 != partial { - cur_token = length - } - current_block = 12693738997172594219; - break; - } else { - match state { - 1 => { - if count > 0i32 as libc::size_t { - r = write_decoded_qp(mmapstr, start, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 13807130624542804568; - break; - } else { - written = (written as libc::size_t).wrapping_add(count) as size_t - as size_t; - count = 0i32 as size_t - } - } - match *message.offset(cur_token as isize) as libc::c_int { - 61 => { - if cur_token.wrapping_add(1i32 as libc::size_t) >= length { - if 0 != partial { - state = STATE_OUT as libc::c_int - } else { - state = STATE_NORMAL as libc::c_int; - start = message.offset(cur_token as isize); - cur_token = cur_token.wrapping_add(1); - count = count.wrapping_add(1) - } - } else { - match *message.offset( - cur_token.wrapping_add(1i32 as libc::size_t) as isize, - ) as libc::c_int - { - 10 => { - cur_token = (cur_token as libc::size_t) - .wrapping_add(2i32 as libc::size_t) - as size_t - as size_t; - start = message.offset(cur_token as isize); - state = STATE_NORMAL as libc::c_int - } - 13 => { - if cur_token.wrapping_add(2i32 as libc::size_t) - >= length - { - state = STATE_OUT as libc::c_int - } else { - if *message.offset( - cur_token.wrapping_add(2i32 as libc::size_t) - as isize, - ) - as libc::c_int - == '\n' as i32 - { - cur_token = (cur_token as libc::size_t) - .wrapping_add(3i32 as libc::size_t) - as size_t - as size_t - } else { - cur_token = (cur_token as libc::size_t) - .wrapping_add(2i32 as libc::size_t) - as size_t - as size_t - } - start = message.offset(cur_token as isize); - state = STATE_NORMAL as libc::c_int - } - } - _ => { - if cur_token.wrapping_add(2i32 as libc::size_t) - >= length - { - if 0 != partial { - state = STATE_OUT as libc::c_int - } else { - cur_token = cur_token.wrapping_add(1); - start = message.offset(cur_token as isize); - count = count.wrapping_add(1); - state = STATE_NORMAL as libc::c_int - } - } else { - ch = to_char( - message - .offset(cur_token as isize) - .offset(1isize), - ); - if mmap_string_append_c(mmapstr, ch).is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13807130624542804568; - break; - } else { - cur_token = (cur_token as libc::size_t) - .wrapping_add(3i32 as libc::size_t) - as size_t - as size_t; - written = written.wrapping_add(1); - start = message.offset(cur_token as isize); - state = STATE_NORMAL as libc::c_int - } - } - } - } - } - } - _ => {} - } - } - 0 => { - /* end of STATE_ENCODED */ - match *message.offset(cur_token as isize) as libc::c_int { - 61 => { - state = STATE_CODED as libc::c_int; - current_block = 3024367268842933116; - } - 10 => { - /* flush before writing additionnal information */ - if count > 0i32 as libc::size_t { - r = write_decoded_qp(mmapstr, start, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 13807130624542804568; - break; - } else { - written = (written as libc::size_t).wrapping_add(count) - as size_t - as size_t; - count = 0i32 as size_t - } - } - r = write_decoded_qp( - mmapstr, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 13807130624542804568; - break; - } else { - written = (written as libc::size_t) - .wrapping_add(2i32 as libc::size_t) - as size_t - as size_t; - cur_token = cur_token.wrapping_add(1); - start = message.offset(cur_token as isize) - } - current_block = 3024367268842933116; - } - 13 => { - state = STATE_CR as libc::c_int; - cur_token = cur_token.wrapping_add(1); - current_block = 3024367268842933116; - } - 95 => { - if 0 != in_header { - if count > 0i32 as libc::size_t { - r = write_decoded_qp(mmapstr, start, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 13807130624542804568; - break; - } else { - written = (written as libc::size_t).wrapping_add(count) - as size_t - as size_t; - count = 0i32 as size_t - } - } - if mmap_string_append_c(mmapstr, ' ' as i32 as libc::c_char) - .is_null() - { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13807130624542804568; - break; - } else { - written = written.wrapping_add(1); - cur_token = cur_token.wrapping_add(1); - start = message.offset(cur_token as isize) - } - current_block = 3024367268842933116; - } else { - /* WARINING : must be followed by switch default action */ - current_block = 9784205294207992806; - } - } - _ => { - current_block = 9784205294207992806; - } - } - match current_block { - 9784205294207992806 => { - if count >= 512i32 as libc::size_t { - r = write_decoded_qp(mmapstr, start, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 13807130624542804568; - break; - } else { - written = (written as libc::size_t).wrapping_add(count) - as size_t - as size_t; - count = 0i32 as size_t; - start = message.offset(cur_token as isize) - } - } - count = count.wrapping_add(1); - cur_token = cur_token.wrapping_add(1) - } - _ => {} - } - } - 3 => { - /* end of STATE_NORMAL */ - match *message.offset(cur_token as isize) as libc::c_int { - 10 => { - /* flush before writing additionnal information */ - if count > 0i32 as libc::size_t { - r = write_decoded_qp(mmapstr, start, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 13807130624542804568; - break; - } else { - written = (written as libc::size_t).wrapping_add(count) - as size_t - as size_t; - count = 0i32 as size_t - } - } - r = write_decoded_qp( - mmapstr, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 13807130624542804568; - break; - } else { - written = (written as libc::size_t) - .wrapping_add(2i32 as libc::size_t) - as size_t - as size_t; - cur_token = cur_token.wrapping_add(1); - start = message.offset(cur_token as isize); - state = STATE_NORMAL as libc::c_int - } - } - _ => { - /* flush before writing additionnal information */ - if count > 0i32 as libc::size_t { - r = write_decoded_qp(mmapstr, start, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 13807130624542804568; - break; - } else { - written = (written as libc::size_t).wrapping_add(count) - as size_t - as size_t; - count = 0i32 as size_t - } - } - start = message.offset(cur_token as isize); - r = write_decoded_qp( - mmapstr, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 13807130624542804568; - break; - } else { - written = (written as libc::size_t) - .wrapping_add(2i32 as libc::size_t) - as size_t - as size_t; - state = STATE_NORMAL as libc::c_int - } - } - } - } - _ => {} - } - } - } - /* end of STATE_CR */ - match current_block { - 12693738997172594219 => { - if count > 0i32 as libc::size_t { - r = write_decoded_qp(mmapstr, start, count); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 13807130624542804568; - } else { - written = (written as libc::size_t).wrapping_add(count) as size_t as size_t; - count = 0i32 as size_t; - current_block = 9255187738567101705; - } - } else { - current_block = 9255187738567101705; - } - match current_block { - 13807130624542804568 => {} - _ => { - r = mmap_string_ref(mmapstr); - if r < 0i32 { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *indx = cur_token; - *result = (*mmapstr).str_0; - *result_len = written; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - _ => {} - } - mmap_string_free(mmapstr); - } - return res; -} -unsafe fn write_decoded_qp( - mut mmapstr: *mut MMAPString, - mut start: *const libc::c_char, - mut count: size_t, -) -> libc::c_int { - if mmap_string_append_len(mmapstr, start, count).is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -#[inline] -unsafe fn to_char(mut hexa: *const libc::c_char) -> libc::c_char { - return (hexa_to_char(*hexa.offset(0isize)) << 4i32 | hexa_to_char(*hexa.offset(1isize))) - as libc::c_char; -} -#[inline] -unsafe fn hexa_to_char(mut hexdigit: libc::c_char) -> libc::c_int { - if hexdigit as libc::c_int >= '0' as i32 && hexdigit as libc::c_int <= '9' as i32 { - return hexdigit as libc::c_int - '0' as i32; - } - if hexdigit as libc::c_int >= 'a' as i32 && hexdigit as libc::c_int <= 'f' as i32 { - return hexdigit as libc::c_int - 'a' as i32 + 10i32; - } - if hexdigit as libc::c_int >= 'A' as i32 && hexdigit as libc::c_int <= 'F' as i32 { - return hexdigit as libc::c_int - 'A' as i32 + 10i32; - } - return 0i32; -} - -pub unsafe fn mailmime_binary_body_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, - mut result_len: *mut size_t, -) -> libc::c_int { - let mut mmapstr: *mut MMAPString = 0 as *mut MMAPString; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - mmapstr = mmap_string_new_len( - message.offset(cur_token as isize), - length.wrapping_sub(cur_token), - ); - if mmapstr.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - r = mmap_string_ref(mmapstr); - if r < 0i32 { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - mmap_string_free(mmapstr); - } else { - *indx = length; - *result = (*mmapstr).str_0; - *result_len = length.wrapping_sub(cur_token); - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} -/* -mailmime_part_parse() - -This function gets full MIME part for parsing at once. -It is not suitable, if we want parse incomplete message in a stream mode. - -@return the return code is one of MAILIMF_ERROR_XXX or - MAILIMF_NO_ERROR codes -*/ -pub unsafe fn mailmime_part_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut encoding: libc::c_int, - mut result: *mut *mut libc::c_char, - mut result_len: *mut size_t, -) -> libc::c_int { - return mailmime_part_parse_impl(message, length, indx, encoding, result, result_len, 0i32); -} -unsafe fn mailmime_part_parse_impl( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut encoding: libc::c_int, - mut result: *mut *mut libc::c_char, - mut result_len: *mut size_t, - mut partial: libc::c_int, -) -> libc::c_int { - match encoding { - 5 => { - return mailmime_base64_body_parse_impl( - message, length, indx, result, result_len, partial, - ) - } - 4 => { - return mailmime_quoted_printable_body_parse_impl( - message, length, indx, result, result_len, 0i32, partial, - ) - } - 1 | 2 | 3 | _ => { - return mailmime_binary_body_parse(message, length, indx, result, result_len) - } - }; -} -/* -mailmime_part_parse_partial() - -This function may parse incomplete MIME part (i.e. in streaming mode). -It stops when detect incomplete encoding unit at the end of data. -Position of the first unparsed byte will be returned in (*indx) value. - -For parsing last portion of data must be used mailmime_part_parse() version. - -@param message Message for unparsed data. -@param length Length of the unparsed data. -@param INOUT indx Index of first unparsed symbol in the message. -@param encoding Encoding of the input data. -@param result Parsed MIME part content. Must be freed with mmap_string_unref(). -@param result_len Length of parsed data. - -@return the return code is one of MAILIMF_ERROR_XXX or - MAILIMF_NO_ERROR codes - -Example Usage: -@code -uint32_t received = 0; -uint32_t partLength = bodystructure[partId]->length; -for (;;) { - bool isThisRangeLast; - struct imap_range_t range = { received, 1024*1024 }; - char *result; - size_t result_len; - int error = imap_fetch_part_range(uid, partId, range, &result, &result_len); - if (error != NoError) { - // handle network error - break; - } - - if (result_len == 0) { - // requested range is empty. part is completely fetched - break; - } - - isThisRangeLast = (received + result_len >= partLength); // determine that the received data is the last, - // may be more difficult (in case of invalid metadata on the server). - - char *decoded; - size_t decoded_len; - if (isThisRangeLast) { - uint32_t index = 0; - mailmime_part_parse(result, result_len, encoding, &index, &decoded, &decoded_len); - break; - } - else { - uint32_t index = 0; - mailmime_part_parse_partial(result, result_len, encoding, &index, &decoded, &decoded_len); - // we may have some non-decoded bytes at the end of chunk. - // in this case we just request it in the next chunk - received += index; - } -} -@endcode -*/ -pub unsafe fn mailmime_part_parse_partial( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut encoding: libc::c_int, - mut result: *mut *mut libc::c_char, - mut result_len: *mut size_t, -) -> libc::c_int { - return mailmime_part_parse_impl(message, length, indx, encoding, result, result_len, 1i32); -} - -pub unsafe fn mailmime_get_section_id( - mut mime: *mut Mailmime, - mut result: *mut *mut mailmime_section, -) -> libc::c_int { - let mut current_block: u64; - let mut list: *mut clist = 0 as *mut clist; - let mut res: libc::c_int = 0; - let mut section_id: *mut mailmime_section = 0 as *mut mailmime_section; - let mut r: libc::c_int = 0; - if (*mime).mm_parent.is_null() { - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 11086394427076829997; - } else { - section_id = mailmime_section_new(list); - if section_id.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 11086394427076829997; - } else { - current_block = 9441801433784995173; - } - } - } else { - let mut id: uint32_t = 0; - let mut p_id: *mut uint32_t = 0 as *mut uint32_t; - let mut cur: *mut clistiter = 0 as *mut clistiter; - let mut parent: *mut Mailmime = 0 as *mut Mailmime; - r = mailmime_get_section_id((*mime).mm_parent, &mut section_id); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 11086394427076829997; - } else { - parent = (*mime).mm_parent; - match (*parent).mm_type { - 2 => { - current_block = 12048923724182970853; - match current_block { - 14310756207842895454 => { - if (*mime).mm_type == MAILMIME_SINGLE as libc::c_int - || (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int - { - p_id = malloc(::std::mem::size_of::() as libc::size_t) - as *mut uint32_t; - if p_id.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14847554122685898769; - } else { - *p_id = 1i32 as uint32_t; - r = clist_insert_after( - (*section_id).sec_list, - (*(*section_id).sec_list).last, - p_id as *mut libc::c_void, - ); - if r < 0i32 { - free(p_id as *mut libc::c_void); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14847554122685898769; - } else { - current_block = 9441801433784995173; - } - } - } else { - current_block = 9441801433784995173; - } - } - _ => { - id = 1i32 as uint32_t; - cur = (*(*parent).mm_data.mm_multipart.mm_mp_list).first; - while !cur.is_null() { - if if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - } == mime as *mut libc::c_void - { - break; - } - id = id.wrapping_add(1); - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - p_id = malloc(::std::mem::size_of::() as libc::size_t) - as *mut uint32_t; - if p_id.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14847554122685898769; - } else { - *p_id = id; - r = clist_insert_after( - (*section_id).sec_list, - (*(*section_id).sec_list).last, - p_id as *mut libc::c_void, - ); - if r < 0i32 { - free(p_id as *mut libc::c_void); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14847554122685898769; - } else { - current_block = 9441801433784995173; - } - } - } - } - match current_block { - 9441801433784995173 => {} - _ => { - mailmime_section_free(section_id); - current_block = 11086394427076829997; - } - } - } - 3 => { - current_block = 14310756207842895454; - match current_block { - 14310756207842895454 => { - if (*mime).mm_type == MAILMIME_SINGLE as libc::c_int - || (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int - { - p_id = malloc(::std::mem::size_of::() as libc::size_t) - as *mut uint32_t; - if p_id.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14847554122685898769; - } else { - *p_id = 1i32 as uint32_t; - r = clist_insert_after( - (*section_id).sec_list, - (*(*section_id).sec_list).last, - p_id as *mut libc::c_void, - ); - if r < 0i32 { - free(p_id as *mut libc::c_void); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14847554122685898769; - } else { - current_block = 9441801433784995173; - } - } - } else { - current_block = 9441801433784995173; - } - } - _ => { - id = 1i32 as uint32_t; - cur = (*(*parent).mm_data.mm_multipart.mm_mp_list).first; - while !cur.is_null() { - if if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - } == mime as *mut libc::c_void - { - break; - } - id = id.wrapping_add(1); - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - p_id = malloc(::std::mem::size_of::() as libc::size_t) - as *mut uint32_t; - if p_id.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14847554122685898769; - } else { - *p_id = id; - r = clist_insert_after( - (*section_id).sec_list, - (*(*section_id).sec_list).last, - p_id as *mut libc::c_void, - ); - if r < 0i32 { - free(p_id as *mut libc::c_void); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14847554122685898769; - } else { - current_block = 9441801433784995173; - } - } - } - } - match current_block { - 9441801433784995173 => {} - _ => { - mailmime_section_free(section_id); - current_block = 11086394427076829997; - } - } - } - _ => { - current_block = 9441801433784995173; - } - } - } - } - match current_block { - 11086394427076829997 => return res, - _ => { - *result = section_id; - return MAILIMF_NO_ERROR as libc::c_int; - } - }; -} diff --git a/mmime/src/mailmime/decode.rs b/mmime/src/mailmime/decode.rs deleted file mode 100644 index 3754d8187..000000000 --- a/mmime/src/mailmime/decode.rs +++ /dev/null @@ -1,860 +0,0 @@ -use libc; -use libc::toupper; - -use crate::charconv::*; -use crate::mailimf::*; -use crate::mailmime::content::*; -use crate::mailmime::types::*; -use crate::mmapstring::*; -use crate::other::*; - -pub const TYPE_WORD: libc::c_uint = 1; -pub const TYPE_ENCODED_WORD: libc::c_uint = 2; -pub const MAILMIME_ENCODING_Q: libc::c_uint = 1; -pub const MAILMIME_ENCODING_B: libc::c_uint = 0; -pub const TYPE_ERROR: libc::c_uint = 0; - -pub unsafe fn mailmime_encoded_phrase_parse( - mut default_fromcode: *const libc::c_char, - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut tocode: *const libc::c_char, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut current_block: u64; - let mut gphrase: *mut MMAPString = 0 as *mut MMAPString; - let mut word: *mut mailmime_encoded_word = 0 as *mut mailmime_encoded_word; - let mut first: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut str: *mut libc::c_char = 0 as *mut libc::c_char; - let mut wordutf8: *mut libc::c_char = 0 as *mut libc::c_char; - let mut type_0: libc::c_int = 0; - let mut missing_closing_quote: libc::c_int = 0; - cur_token = *indx; - gphrase = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char); - if gphrase.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - first = 1i32; - type_0 = TYPE_ERROR as libc::c_int; - loop { - let mut has_fwd: libc::c_int = 0; - word = 0 as *mut mailmime_encoded_word; - r = mailmime_encoded_word_parse( - message, - length, - &mut cur_token, - &mut word, - &mut has_fwd, - &mut missing_closing_quote, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - if 0 == first && 0 != has_fwd { - if type_0 != TYPE_ENCODED_WORD as libc::c_int { - if mmap_string_append_c(gphrase, ' ' as i32 as libc::c_char).is_null() { - mailmime_encoded_word_free(word); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13246848547199022064; - break; - } - } - } - type_0 = TYPE_ENCODED_WORD as libc::c_int; - wordutf8 = 0 as *mut libc::c_char; - r = charconv( - tocode, - (*word).wd_charset, - (*word).wd_text, - strlen((*word).wd_text), - &mut wordutf8, - ); - match r { - 2 => { - mailmime_encoded_word_free(word); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13246848547199022064; - break; - } - 1 => { - r = charconv( - tocode, - b"iso-8859-1\x00" as *const u8 as *const libc::c_char, - (*word).wd_text, - strlen((*word).wd_text), - &mut wordutf8, - ) - } - 3 => { - mailmime_encoded_word_free(word); - res = MAILIMF_ERROR_PARSE as libc::c_int; - current_block = 13246848547199022064; - break; - } - _ => {} - } - match r { - 2 => { - mailmime_encoded_word_free(word); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13246848547199022064; - break; - } - 3 => { - mailmime_encoded_word_free(word); - res = MAILIMF_ERROR_PARSE as libc::c_int; - current_block = 13246848547199022064; - break; - } - _ => { - if !wordutf8.is_null() { - if mmap_string_append(gphrase, wordutf8).is_null() { - mailmime_encoded_word_free(word); - free(wordutf8 as *mut libc::c_void); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13246848547199022064; - break; - } else { - free(wordutf8 as *mut libc::c_void); - } - } - mailmime_encoded_word_free(word); - first = 0i32 - } - } - } else if !(r == MAILIMF_ERROR_PARSE as libc::c_int) { - /* do nothing */ - res = r; - current_block = 13246848547199022064; - break; - } - if !(r == MAILIMF_ERROR_PARSE as libc::c_int) { - continue; - } - let mut raw_word: *mut libc::c_char = 0 as *mut libc::c_char; - raw_word = 0 as *mut libc::c_char; - r = mailmime_non_encoded_word_parse( - message, - length, - &mut cur_token, - &mut raw_word, - &mut has_fwd, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - if 0 == first && 0 != has_fwd { - if mmap_string_append_c(gphrase, ' ' as i32 as libc::c_char).is_null() { - free(raw_word as *mut libc::c_void); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13246848547199022064; - break; - } - } - type_0 = TYPE_WORD as libc::c_int; - wordutf8 = 0 as *mut libc::c_char; - r = charconv( - tocode, - default_fromcode, - raw_word, - strlen(raw_word), - &mut wordutf8, - ); - match r { - 2 => { - free(raw_word as *mut libc::c_void); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13246848547199022064; - break; - } - 1 | 3 => { - free(raw_word as *mut libc::c_void); - res = MAILIMF_ERROR_PARSE as libc::c_int; - current_block = 13246848547199022064; - break; - } - _ => { - if mmap_string_append(gphrase, wordutf8).is_null() { - free(wordutf8 as *mut libc::c_void); - free(raw_word as *mut libc::c_void); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13246848547199022064; - break; - } else { - free(wordutf8 as *mut libc::c_void); - free(raw_word as *mut libc::c_void); - first = 0i32 - } - } - } - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_fws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 5005389895767293342; - break; - } - if mmap_string_append_c(gphrase, ' ' as i32 as libc::c_char).is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13246848547199022064; - break; - } else { - first = 0i32; - current_block = 5005389895767293342; - break; - } - } else { - res = r; - current_block = 13246848547199022064; - break; - } - } - match current_block { - 5005389895767293342 => { - if 0 != first { - if cur_token != length { - res = MAILIMF_ERROR_PARSE as libc::c_int; - current_block = 13246848547199022064; - } else { - current_block = 7072655752890836508; - } - } else { - current_block = 7072655752890836508; - } - match current_block { - 13246848547199022064 => {} - _ => { - str = strdup((*gphrase).str_0); - if str.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - mmap_string_free(gphrase); - *result = str; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - _ => {} - } - mmap_string_free(gphrase); - } - return res; -} -unsafe fn mailmime_non_encoded_word_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, - mut p_has_fwd: *mut libc::c_int, -) -> libc::c_int { - let mut end: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut res: libc::c_int = 0; - let mut text: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - let mut begin: size_t = 0; - let mut state: libc::c_int = 0; - let mut has_fwd: libc::c_int = 0; - cur_token = *indx; - has_fwd = 0i32; - r = mailimf_fws_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - has_fwd = 1i32 - } - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - begin = cur_token; - state = 0i32; - end = 0i32; - while !(cur_token >= length) { - let mut current_block_17: u64; - match *message.offset(cur_token as isize) as libc::c_int { - 32 | 9 | 13 | 10 => { - state = 0i32; - end = 1i32; - current_block_17 = 16924917904204750491; - } - 61 => { - state = 1i32; - current_block_17 = 16924917904204750491; - } - 63 => { - if state == 1i32 { - cur_token = cur_token.wrapping_sub(1); - end = 1i32 - } - current_block_17 = 10192508258555769664; - } - _ => { - current_block_17 = 10192508258555769664; - } - } - match current_block_17 { - 10192508258555769664 => state = 0i32, - _ => {} - } - if 0 != end { - break; - } - cur_token = cur_token.wrapping_add(1) - } - if cur_token.wrapping_sub(begin) == 0i32 as libc::size_t { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - text = malloc( - cur_token - .wrapping_sub(begin) - .wrapping_add(1i32 as libc::size_t), - ) as *mut libc::c_char; - if text.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - memcpy( - text as *mut libc::c_void, - message.offset(begin as isize) as *const libc::c_void, - cur_token.wrapping_sub(begin), - ); - *text.offset(cur_token.wrapping_sub(begin) as isize) = - '\u{0}' as i32 as libc::c_char; - *indx = cur_token; - *result = text; - *p_has_fwd = has_fwd; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - return res; -} - -pub unsafe fn mailmime_encoded_word_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_encoded_word, - mut p_has_fwd: *mut libc::c_int, - mut p_missing_closing_quote: *mut libc::c_int, -) -> libc::c_int { - let mut current_block: u64; - /* - Parse the following, when a unicode character encoding is split. - =?UTF-8?B?4Lij4Liw4LmA4Lia4Li04LiU4LiE4Lin4Liy4Lih4Lih4Lix4LiZ4Liq4LmM?= - =?UTF-8?B?4LmA4LiV4LmH4Lih4Lie4Li04LiB4Lix4LiUIFRSQU5TRk9STUVSUyA0IOC4?= - =?UTF-8?B?oeC4seC4meC4quC5jOC4hOC4o+C4muC4l+C4uOC4geC4o+C4sOC4muC4miDg?= - =?UTF-8?B?uJfguLXguYjguYDguJTguLXguKLguKfguYPguJnguYDguKHguLfguK3guIfg?= - =?UTF-8?B?uYTguJfguKI=?= - Expected result: - ระเบิดความมันส์เต็มพิกัด TRANSFORMERS 4 มันส์ครบทุกระบบ ที่เดียวในเมืองไทย - libetpan result: - ระเบิดความมันส์เต็มพิกัด TRANSFORMERS 4 ?ันส์ครบทุกระบบ ??ี่เดียวในเมือง??ทย - - See https://github.com/dinhviethoa/libetpan/pull/211 - */ - let mut cur_token: size_t = 0; - let mut charset: *mut libc::c_char = 0 as *mut libc::c_char; - let mut encoding: libc::c_int = 0; - let mut body: *mut libc::c_char = 0 as *mut libc::c_char; - let mut old_body_len: size_t = 0; - let mut text: *mut libc::c_char = 0 as *mut libc::c_char; - let mut end_encoding: size_t = 0; - let mut lookfwd_cur_token: size_t = 0; - let mut lookfwd_charset: *mut libc::c_char = 0 as *mut libc::c_char; - let mut lookfwd_encoding: libc::c_int = 0; - let mut copy_len: size_t = 0; - let mut decoded_token: size_t = 0; - let mut decoded: *mut libc::c_char = 0 as *mut libc::c_char; - let mut decoded_len: size_t = 0; - let mut ew: *mut mailmime_encoded_word = 0 as *mut mailmime_encoded_word; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut opening_quote: libc::c_int = 0; - let mut end: libc::c_int = 0; - let mut has_fwd: libc::c_int = 0; - let mut missing_closing_quote: libc::c_int = 0; - cur_token = *indx; - text = 0 as *mut libc::c_char; - lookfwd_charset = 0 as *mut libc::c_char; - missing_closing_quote = 0i32; - has_fwd = 0i32; - r = mailimf_fws_parse(message, length, &mut cur_token); - if r == MAILIMF_NO_ERROR as libc::c_int { - has_fwd = 1i32 - } - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - opening_quote = 0i32; - r = mailimf_char_parse(message, length, &mut cur_token, '\"' as i32 as libc::c_char); - if r == MAILIMF_NO_ERROR as libc::c_int { - opening_quote = 1i32; - current_block = 17788412896529399552; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 17788412896529399552; - } else { - /* do nothing */ - res = r; - current_block = 7995813543095296079; - } - match current_block { - 7995813543095296079 => {} - _ => { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"=?\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"=?\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailmime_charset_parse(message, length, &mut cur_token, &mut charset); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_char_parse( - message, - length, - &mut cur_token, - '?' as i32 as libc::c_char, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailmime_encoding_parse( - message, - length, - &mut cur_token, - &mut encoding, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_char_parse( - message, - length, - &mut cur_token, - '?' as i32 as libc::c_char, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - lookfwd_cur_token = cur_token; - body = 0 as *mut libc::c_char; - old_body_len = 0i32 as size_t; - loop { - let mut has_base64_padding: libc::c_int = 0; - end = 0i32; - has_base64_padding = 0i32; - end_encoding = cur_token; - while !(end_encoding >= length) { - if end_encoding.wrapping_add(1i32 as libc::size_t) - < length - { - if *message.offset(end_encoding as isize) - as libc::c_int - == '?' as i32 - && *message.offset( - end_encoding - .wrapping_add(1i32 as libc::size_t) - as isize, - ) - as libc::c_int - == '=' as i32 - { - end = 1i32 - } - } - if 0 != end { - break; - } - end_encoding = end_encoding.wrapping_add(1) - } - copy_len = end_encoding.wrapping_sub(lookfwd_cur_token); - if copy_len > 0i32 as libc::size_t { - if encoding == MAILMIME_ENCODING_B as libc::c_int { - if end_encoding >= 1i32 as libc::size_t { - if *message.offset( - end_encoding - .wrapping_sub(1i32 as libc::size_t) - as isize, - ) - as libc::c_int - == '=' as i32 - { - has_base64_padding = 1i32 - } - } - } - body = realloc( - body as *mut libc::c_void, - old_body_len - .wrapping_add(copy_len) - .wrapping_add(1i32 as libc::size_t), - ) - as *mut libc::c_char; - if body.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13900684162107791171; - break; - } else { - memcpy( - body.offset(old_body_len as isize) - as *mut libc::c_void, - &*message.offset(cur_token as isize) - as *const libc::c_char - as *const libc::c_void, - copy_len, - ); - *body - .offset(old_body_len.wrapping_add(copy_len) - as isize) = '\u{0}' as i32 as libc::c_char; - old_body_len = (old_body_len as libc::size_t) - .wrapping_add(copy_len) - as size_t - as size_t - } - } - cur_token = end_encoding; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"?=\x00" as *const u8 as *const libc::c_char - as *mut libc::c_char, - strlen(b"?=\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 2652804691515851435; - break; - } - if 0 != has_base64_padding { - current_block = 2652804691515851435; - break; - } - lookfwd_cur_token = cur_token; - r = mailimf_fws_parse( - message, - length, - &mut lookfwd_cur_token, - ); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - current_block = 2652804691515851435; - break; - } - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut lookfwd_cur_token, - b"=?\x00" as *const u8 as *const libc::c_char - as *mut libc::c_char, - strlen(b"=?\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 2652804691515851435; - break; - } - r = mailmime_charset_parse( - message, - length, - &mut lookfwd_cur_token, - &mut lookfwd_charset, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 2652804691515851435; - break; - } - r = mailimf_char_parse( - message, - length, - &mut lookfwd_cur_token, - '?' as i32 as libc::c_char, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 2652804691515851435; - break; - } - r = mailmime_encoding_parse( - message, - length, - &mut lookfwd_cur_token, - &mut lookfwd_encoding, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 2652804691515851435; - break; - } - r = mailimf_char_parse( - message, - length, - &mut lookfwd_cur_token, - '?' as i32 as libc::c_char, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 2652804691515851435; - break; - } - if strcasecmp(charset, lookfwd_charset) == 0i32 - && encoding == lookfwd_encoding - { - cur_token = lookfwd_cur_token; - mailmime_charset_free(lookfwd_charset); - lookfwd_charset = 0 as *mut libc::c_char - } else { - /* the next charset is not matched with the current one, - therefore exit the loop to decode the body appended so far */ - current_block = 2652804691515851435; - break; - } - } - match current_block { - 2652804691515851435 => { - if !lookfwd_charset.is_null() { - mailmime_charset_free(lookfwd_charset); - lookfwd_charset = 0 as *mut libc::c_char - } - if body.is_null() { - body = strdup( - b"\x00" as *const u8 as *const libc::c_char, - ); - if body.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13900684162107791171; - } else { - current_block = 16778110326724371720; - } - } else { - current_block = 16778110326724371720; - } - match current_block { - 13900684162107791171 => {} - _ => { - decoded_token = 0i32 as size_t; - decoded_len = 0i32 as size_t; - decoded = 0 as *mut libc::c_char; - match encoding { - 0 => { - r = mailmime_base64_body_parse( - body, - strlen(body), - &mut decoded_token, - &mut decoded, - &mut decoded_len, - ); - if r != MAILIMF_NO_ERROR as libc::c_int - { - res = r; - current_block = - 13900684162107791171; - } else { - current_block = 7337917895049117968; - } - } - 1 => { - r = - mailmime_quoted_printable_body_parse(body, - strlen(body), - &mut decoded_token, - &mut decoded, - &mut decoded_len, - 1i32); - if r != MAILIMF_NO_ERROR as libc::c_int - { - res = r; - current_block = - 13900684162107791171; - } else { - current_block = 7337917895049117968; - } - } - _ => { - current_block = 7337917895049117968; - } - } - match current_block { - 13900684162107791171 => {} - _ => { - text = - malloc(decoded_len.wrapping_add( - 1i32 as libc::size_t, - )) - as *mut libc::c_char; - if text.is_null() { - res = MAILIMF_ERROR_MEMORY - as libc::c_int - } else { - if decoded_len - > 0i32 as libc::size_t - { - memcpy( - text as *mut libc::c_void, - decoded - as *const libc::c_void, - decoded_len, - ); - } - *text - .offset(decoded_len as isize) = - '\u{0}' as i32 as libc::c_char; - if 0 != opening_quote { - r = mailimf_char_parse( - message, - length, - &mut cur_token, - '\"' as i32 as libc::c_char, - ); - if r == MAILIMF_ERROR_PARSE - as libc::c_int - { - missing_closing_quote = 1i32 - } - } - if strcasecmp( - charset, - b"utf8\x00" as *const u8 - as *const libc::c_char, - ) == 0i32 - { - free( - charset - as *mut libc::c_void, - ); - charset = strdup( - b"utf-8\x00" as *const u8 - as *const libc::c_char, - ) - } - ew = mailmime_encoded_word_new( - charset, text, - ); - if ew.is_null() { - res = MAILIMF_ERROR_MEMORY - as libc::c_int - } else { - *result = ew; - *indx = cur_token; - *p_has_fwd = has_fwd; - *p_missing_closing_quote = - missing_closing_quote; - mailmime_decoded_part_free( - decoded, - ); - free(body as *mut libc::c_void); - return MAILIMF_NO_ERROR - as libc::c_int; - } - } - mailmime_decoded_part_free(decoded); - } - } - } - } - } - _ => {} - } - free(body as *mut libc::c_void); - mailmime_encoded_text_free(text); - } - } - } - mailmime_charset_free(charset); - } - } - } - } - } - return res; -} -unsafe fn mailmime_encoding_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut libc::c_int, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut encoding: libc::c_int = 0; - cur_token = *indx; - if cur_token >= length { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - match toupper(*message.offset(cur_token as isize) as libc::c_uchar as libc::c_int) - as libc::c_char as libc::c_int - { - 81 => encoding = MAILMIME_ENCODING_Q as libc::c_int, - 66 => encoding = MAILMIME_ENCODING_B as libc::c_int, - _ => return MAILIMF_ERROR_INVAL as libc::c_int, - } - cur_token = cur_token.wrapping_add(1); - *result = encoding; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} - -/* - * libEtPan! -- a mail stuff library - * - * Copyright (C) 2001, 2005 - DINH Viet Hoa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the libEtPan! project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * $Id: mailmime_decode.c,v 1.37 2010/11/16 20:52:28 hoa Exp $ - */ -/* - RFC 2047 : MIME (Multipurpose Internet Mail Extensions) Part Three: - Message Header Extensions for Non-ASCII Text -*/ -unsafe fn mailmime_charset_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut charset: *mut *mut libc::c_char, -) -> libc::c_int { - return mailmime_etoken_parse(message, length, indx, charset); -} -unsafe fn mailmime_etoken_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - return mailimf_custom_string_parse(message, length, indx, result, Some(is_etoken_char)); -} - -unsafe fn is_etoken_char(mut ch: libc::c_char) -> libc::c_int { - let mut uch: libc::c_uchar = ch as libc::c_uchar; - if (uch as libc::c_int) < 31i32 { - return 0i32; - } - match uch as libc::c_int { - 32 | 40 | 41 | 60 | 62 | 64 | 44 | 59 | 58 | 34 | 47 | 91 | 93 | 63 | 61 => return 0i32, - _ => {} - } - return 1i32; -} diff --git a/mmime/src/mailmime/disposition.rs b/mmime/src/mailmime/disposition.rs deleted file mode 100644 index 6b68763dd..000000000 --- a/mmime/src/mailmime/disposition.rs +++ /dev/null @@ -1,583 +0,0 @@ -use libc::{self, toupper}; - -use crate::clist::*; -use crate::mailimf::*; -use crate::mailmime::types::*; -use crate::mailmime::*; -use crate::other::*; - -pub const MAILMIME_DISPOSITION_TYPE_EXTENSION: libc::c_uint = 3; -pub const MAILMIME_DISPOSITION_TYPE_ATTACHMENT: libc::c_uint = 2; -pub const MAILMIME_DISPOSITION_TYPE_INLINE: libc::c_uint = 1; -pub const MAILMIME_DISPOSITION_TYPE_ERROR: libc::c_uint = 0; - -pub unsafe fn mailmime_disposition_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_disposition, -) -> libc::c_int { - let mut current_block: u64; - let mut final_token: size_t = 0; - let mut cur_token: size_t = 0; - let mut dsp_type: *mut mailmime_disposition_type = 0 as *mut mailmime_disposition_type; - let mut list: *mut clist = 0 as *mut clist; - let mut dsp: *mut mailmime_disposition = 0 as *mut mailmime_disposition; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailmime_disposition_type_parse(message, length, &mut cur_token, &mut dsp_type); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - loop { - let mut param: *mut mailmime_disposition_parm = 0 as *mut mailmime_disposition_parm; - final_token = cur_token; - r = mailimf_unstrict_char_parse( - message, - length, - &mut cur_token, - ';' as i32 as libc::c_char, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - param = 0 as *mut mailmime_disposition_parm; - r = mailmime_disposition_parm_parse( - message, - length, - &mut cur_token, - &mut param, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - r = clist_insert_after(list, (*list).last, param as *mut libc::c_void); - if !(r < 0i32) { - continue; - } - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 18290070879695007868; - break; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - cur_token = final_token; - current_block = 652864300344834934; - break; - } else { - res = r; - current_block = 18290070879695007868; - break; - } - } else { - /* do nothing */ - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 652864300344834934; - break; - } - res = r; - current_block = 18290070879695007868; - break; - } - } - match current_block { - 652864300344834934 => { - dsp = mailmime_disposition_new(dsp_type, list); - if dsp.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = dsp; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - _ => {} - } - clist_foreach( - list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailmime_disposition_parm_free)), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - mailmime_disposition_type_free(dsp_type); - } - return res; -} -/* - * libEtPan! -- a mail stuff library - * - * Copyright (C) 2001, 2005 - DINH Viet Hoa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the libEtPan! project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * $Id: mailmime_disposition.c,v 1.17 2011/05/03 16:30:22 hoa Exp $ - */ -unsafe fn mailmime_disposition_parm_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_disposition_parm, -) -> libc::c_int { - let mut current_block: u64; - let mut filename: *mut libc::c_char = 0 as *mut libc::c_char; - let mut creation_date: *mut libc::c_char = 0 as *mut libc::c_char; - let mut modification_date: *mut libc::c_char = 0 as *mut libc::c_char; - let mut read_date: *mut libc::c_char = 0 as *mut libc::c_char; - let mut size: size_t = 0; - let mut parameter: *mut mailmime_parameter = 0 as *mut mailmime_parameter; - let mut cur_token: size_t = 0; - let mut dsp_parm: *mut mailmime_disposition_parm = 0 as *mut mailmime_disposition_parm; - let mut type_0: libc::c_int = 0; - let mut guessed_type: libc::c_int = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - filename = 0 as *mut libc::c_char; - creation_date = 0 as *mut libc::c_char; - modification_date = 0 as *mut libc::c_char; - read_date = 0 as *mut libc::c_char; - size = 0i32 as size_t; - parameter = 0 as *mut mailmime_parameter; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - guessed_type = mailmime_disposition_guess_type(message, length, cur_token); - type_0 = MAILMIME_DISPOSITION_PARM_PARAMETER as libc::c_int; - match guessed_type { - 0 => { - r = mailmime_filename_parm_parse(message, length, &mut cur_token, &mut filename); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 13826291924415791078; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 13826291924415791078; - } else { - /* do nothing */ - res = r; - current_block = 9120900589700563584; - } - } - 1 => { - r = mailmime_creation_date_parm_parse( - message, - length, - &mut cur_token, - &mut creation_date, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 13826291924415791078; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 13826291924415791078; - } else { - /* do nothing */ - res = r; - current_block = 9120900589700563584; - } - } - 2 => { - r = mailmime_modification_date_parm_parse( - message, - length, - &mut cur_token, - &mut modification_date, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 13826291924415791078; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 13826291924415791078; - } else { - /* do nothing */ - res = r; - current_block = 9120900589700563584; - } - } - 3 => { - r = mailmime_read_date_parm_parse(message, length, &mut cur_token, &mut read_date); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 13826291924415791078; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 13826291924415791078; - } else { - /* do nothing */ - res = r; - current_block = 9120900589700563584; - } - } - 4 => { - r = mailmime_size_parm_parse(message, length, &mut cur_token, &mut size); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - current_block = 13826291924415791078; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 13826291924415791078; - } else { - /* do nothing */ - res = r; - current_block = 9120900589700563584; - } - } - _ => { - current_block = 13826291924415791078; - } - } - match current_block { - 9120900589700563584 => {} - _ => { - if type_0 == MAILMIME_DISPOSITION_PARM_PARAMETER as libc::c_int { - r = mailmime_parameter_parse(message, length, &mut cur_token, &mut parameter); - if r != MAILIMF_NO_ERROR as libc::c_int { - type_0 = guessed_type; - res = r; - current_block = 9120900589700563584; - } else { - current_block = 6721012065216013753; - } - } else { - current_block = 6721012065216013753; - } - match current_block { - 9120900589700563584 => {} - _ => { - dsp_parm = mailmime_disposition_parm_new( - type_0, - filename, - creation_date, - modification_date, - read_date, - size, - parameter, - ); - if dsp_parm.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !filename.is_null() { - mailmime_filename_parm_free(filename); - } - if !creation_date.is_null() { - mailmime_creation_date_parm_free(creation_date); - } - if !modification_date.is_null() { - mailmime_modification_date_parm_free(modification_date); - } - if !read_date.is_null() { - mailmime_read_date_parm_free(read_date); - } - if !parameter.is_null() { - mailmime_parameter_free(parameter); - } - } else { - *result = dsp_parm; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - } - } - return res; -} -unsafe fn mailmime_size_parm_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut size_t, -) -> libc::c_int { - let mut value: uint32_t = 0; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"size\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"size\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_unstrict_char_parse(message, length, &mut cur_token, '=' as i32 as libc::c_char); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_number_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - *result = value as size_t; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_read_date_parm_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"read-date\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"read-date\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_unstrict_char_parse(message, length, &mut cur_token, '=' as i32 as libc::c_char); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailmime_quoted_date_time_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - *result = value; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_quoted_date_time_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - return mailimf_quoted_string_parse(message, length, indx, result); -} -unsafe fn mailmime_modification_date_parm_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"modification-date\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"modification-date\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_unstrict_char_parse(message, length, &mut cur_token, '=' as i32 as libc::c_char); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailmime_quoted_date_time_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - *result = value; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_creation_date_parm_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - let mut cur_token: size_t = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"creation-date\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"creation-date\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_unstrict_char_parse(message, length, &mut cur_token, '=' as i32 as libc::c_char); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailmime_quoted_date_time_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - *result = value; - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_filename_parm_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut r: libc::c_int = 0; - let mut cur_token: size_t = 0; - cur_token = *indx; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"filename\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"filename\x00" as *const u8 as *const libc::c_char), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_unstrict_char_parse(message, length, &mut cur_token, '=' as i32 as libc::c_char); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailmime_value_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *indx = cur_token; - *result = value; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_disposition_guess_type( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: size_t, -) -> libc::c_int { - if indx >= length { - return MAILMIME_DISPOSITION_PARM_PARAMETER as libc::c_int; - } - match toupper(*message.offset(indx as isize) as libc::c_uchar as libc::c_int) as libc::c_char - as libc::c_int - { - 70 => return MAILMIME_DISPOSITION_PARM_FILENAME as libc::c_int, - 67 => return MAILMIME_DISPOSITION_PARM_CREATION_DATE as libc::c_int, - 77 => return MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE as libc::c_int, - 82 => return MAILMIME_DISPOSITION_PARM_READ_DATE as libc::c_int, - 83 => return MAILMIME_DISPOSITION_PARM_SIZE as libc::c_int, - _ => return MAILMIME_DISPOSITION_PARM_PARAMETER as libc::c_int, - }; -} - -pub unsafe fn mailmime_disposition_type_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_disposition_type, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut type_0: libc::c_int = 0; - let mut extension: *mut libc::c_char = 0 as *mut libc::c_char; - let mut dsp_type: *mut mailmime_disposition_type = 0 as *mut mailmime_disposition_type; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - type_0 = MAILMIME_DISPOSITION_TYPE_ERROR as libc::c_int; - extension = 0 as *mut libc::c_char; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"inline\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"inline\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_DISPOSITION_TYPE_INLINE as libc::c_int - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"attachment\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"attachment\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_DISPOSITION_TYPE_ATTACHMENT as libc::c_int - } - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailmime_extension_token_parse(message, length, &mut cur_token, &mut extension); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_DISPOSITION_TYPE_EXTENSION as libc::c_int - } - } - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - dsp_type = mailmime_disposition_type_new(type_0, extension); - if dsp_type.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !extension.is_null() { - free(extension as *mut libc::c_void); - } - } else { - *result = dsp_type; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - return res; -} diff --git a/mmime/src/mailmime/mod.rs b/mmime/src/mailmime/mod.rs deleted file mode 100644 index d13fe4bdd..000000000 --- a/mmime/src/mailmime/mod.rs +++ /dev/null @@ -1,1143 +0,0 @@ -pub mod content; -pub mod decode; -pub mod disposition; -pub mod types; -pub mod types_helper; -pub(crate) mod write_generic; -pub mod write_mem; - -use libc::toupper; - -use crate::clist::*; -use crate::mailimf::types::*; -use crate::mailimf::*; -use crate::mailmime::decode::*; -use crate::mailmime::disposition::*; -use crate::mailmime::types::*; -use crate::other::*; - -pub const MAILMIME_COMPOSITE_TYPE_EXTENSION: libc::c_uint = 3; -pub const MAILMIME_COMPOSITE_TYPE_MULTIPART: libc::c_uint = 2; -pub const MAILMIME_COMPOSITE_TYPE_MESSAGE: libc::c_uint = 1; -pub const MAILMIME_COMPOSITE_TYPE_ERROR: libc::c_uint = 0; - -pub const MAILMIME_TYPE_COMPOSITE_TYPE: libc::c_uint = 2; -pub const MAILMIME_TYPE_DISCRETE_TYPE: libc::c_uint = 1; -pub const MAILMIME_TYPE_ERROR: libc::c_uint = 0; -pub const FIELD_STATE_L: libc::c_uint = 3; -pub const FIELD_STATE_D: libc::c_uint = 2; -pub const FIELD_STATE_T: libc::c_uint = 1; -pub const FIELD_STATE_START: libc::c_uint = 0; - -pub const MAILMIME_DISCRETE_TYPE_EXTENSION: libc::c_uint = 6; -pub const MAILMIME_DISCRETE_TYPE_APPLICATION: libc::c_uint = 5; -pub const MAILMIME_DISCRETE_TYPE_VIDEO: libc::c_uint = 4; -pub const MAILMIME_DISCRETE_TYPE_AUDIO: libc::c_uint = 3; -pub const MAILMIME_DISCRETE_TYPE_IMAGE: libc::c_uint = 2; -pub const MAILMIME_DISCRETE_TYPE_TEXT: libc::c_uint = 1; -pub const MAILMIME_DISCRETE_TYPE_ERROR: libc::c_uint = 0; - -pub unsafe fn mailmime_content_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_content, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut type_0: *mut mailmime_type = 0 as *mut mailmime_type; - let mut subtype: *mut libc::c_char = 0 as *mut libc::c_char; - let mut parameters_list: *mut clist = 0 as *mut clist; - let mut content: *mut mailmime_content = 0 as *mut mailmime_content; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - mailimf_cfws_parse(message, length, &mut cur_token); - type_0 = 0 as *mut mailmime_type; - r = mailmime_type_parse(message, length, &mut cur_token, &mut type_0); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_char_parse( - message, - length, - &mut cur_token, - '/' as i32 as libc::c_char, - ); - match r { - 0 => { - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r; - current_block = 10242373397628622958; - } else { - r = mailmime_subtype_parse(message, length, &mut cur_token, &mut subtype); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 10242373397628622958; - } else { - current_block = 1109700713171191020; - } - } - } - 1 => { - subtype = strdup(b"unknown\x00" as *const u8 as *const libc::c_char); - current_block = 1109700713171191020; - } - _ => { - res = r; - current_block = 10242373397628622958; - } - } - match current_block { - 1109700713171191020 => { - parameters_list = clist_new(); - if parameters_list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - loop { - let mut final_token: size_t = 0; - let mut parameter: *mut mailmime_parameter = 0 as *mut mailmime_parameter; - final_token = cur_token; - r = mailimf_unstrict_char_parse( - message, - length, - &mut cur_token, - ';' as i32 as libc::c_char, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - cur_token = final_token; - current_block = 12497913735442871383; - break; - } else { - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int - && r != MAILIMF_ERROR_PARSE as libc::c_int - { - res = r; - current_block = 6276274620003476740; - break; - } else { - r = mailmime_parameter_parse( - message, - length, - &mut cur_token, - &mut parameter, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - r = clist_insert_after( - parameters_list, - (*parameters_list).last, - parameter as *mut libc::c_void, - ); - if !(r < 0i32) { - continue; - } - mailmime_parameter_free(parameter); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 5731074241326334034; - break; - } else if r == MAILIMF_ERROR_PARSE as libc::c_int { - cur_token = final_token; - current_block = 12497913735442871383; - break; - } else { - res = r; - current_block = 6276274620003476740; - break; - } - } - } - } - match current_block { - 6276274620003476740 => {} - _ => { - match current_block { - 12497913735442871383 => { - content = - mailmime_content_new(type_0, subtype, parameters_list); - if content.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = content; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - _ => {} - } - clist_foreach( - parameters_list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailmime_parameter_free)), - 0 as *mut libc::c_void, - ); - clist_free(parameters_list); - } - } - } - mailmime_subtype_free(subtype); - } - _ => {} - } - mailmime_type_free(type_0); - } - return res; -} - -pub unsafe fn mailmime_parameter_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_parameter, -) -> libc::c_int { - let mut attribute: *mut libc::c_char = 0 as *mut libc::c_char; - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut parameter: *mut mailmime_parameter = 0 as *mut mailmime_parameter; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - r = mailmime_attribute_parse(message, length, &mut cur_token, &mut attribute); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_unstrict_char_parse( - message, - length, - &mut cur_token, - '=' as i32 as libc::c_char, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - res = r - } else { - r = mailmime_value_parse(message, length, &mut cur_token, &mut value); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - parameter = mailmime_parameter_new(attribute, value); - if parameter.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - mailmime_value_free(value); - } else { - *result = parameter; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - } - mailmime_attribute_free(attribute); - } - return res; -} - -pub unsafe fn mailmime_value_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_atom_parse(message, length, indx, result); - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_quoted_string_parse(message, length, indx, result) - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -/* - * libEtPan! -- a mail stuff library - * - * Copyright (C) 2001, 2005 - DINH Viet Hoa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the libEtPan! project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * $Id: mailmime.c,v 1.29 2011/01/06 00:09:52 hoa Exp $ - */ -/* - RFC 2045 - RFC 2046 - RFC 2047 - RFC 2048 - RFC 2049 - RFC 2231 - RFC 2387 - RFC 2424 - RFC 2557 - - RFC 2183 Content-Disposition - - RFC 1766 Language -*/ -unsafe fn mailmime_attribute_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - return mailmime_token_parse(message, length, indx, result); -} -unsafe fn mailmime_token_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut token: *mut *mut libc::c_char, -) -> libc::c_int { - return mailimf_custom_string_parse(message, length, indx, token, Some(is_token)); -} -unsafe fn is_token(mut ch: libc::c_char) -> libc::c_int { - let mut uch: libc::c_uchar = ch as libc::c_uchar; - if uch as libc::c_int > 0x7fi32 { - return 0i32; - } - if uch as libc::c_int == ' ' as i32 { - return 0i32; - } - if 0 != is_tspecials(ch) { - return 0i32; - } - return 1i32; -} -unsafe fn is_tspecials(mut ch: libc::c_char) -> libc::c_int { - match ch as libc::c_int { - 40 | 41 | 60 | 62 | 64 | 44 | 59 | 58 | 92 | 34 | 47 | 91 | 93 | 63 | 61 => return 1i32, - _ => return 0i32, - }; -} -unsafe fn mailmime_subtype_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - return mailmime_extension_token_parse(message, length, indx, result); -} - -pub unsafe fn mailmime_extension_token_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - return mailmime_token_parse(message, length, indx, result); -} -unsafe fn mailmime_type_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_type, -) -> libc::c_int { - let mut discrete_type: *mut mailmime_discrete_type = 0 as *mut mailmime_discrete_type; - let mut composite_type: *mut mailmime_composite_type = 0 as *mut mailmime_composite_type; - let mut cur_token: size_t = 0; - let mut mime_type: *mut mailmime_type = 0 as *mut mailmime_type; - let mut type_0: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - discrete_type = 0 as *mut mailmime_discrete_type; - composite_type = 0 as *mut mailmime_composite_type; - type_0 = MAILMIME_TYPE_ERROR as libc::c_int; - r = mailmime_composite_type_parse(message, length, &mut cur_token, &mut composite_type); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailmime_discrete_type_parse(message, length, &mut cur_token, &mut discrete_type); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_TYPE_DISCRETE_TYPE as libc::c_int - } - } - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - mime_type = mailmime_type_new(type_0, discrete_type, composite_type); - if mime_type.is_null() { - res = r; - if !discrete_type.is_null() { - mailmime_discrete_type_free(discrete_type); - } - if !composite_type.is_null() { - mailmime_composite_type_free(composite_type); - } - } else { - *result = mime_type; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} -unsafe fn mailmime_discrete_type_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_discrete_type, -) -> libc::c_int { - let mut extension: *mut libc::c_char = 0 as *mut libc::c_char; - let mut type_0: libc::c_int = 0; - let mut discrete_type: *mut mailmime_discrete_type = 0 as *mut mailmime_discrete_type; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - extension = 0 as *mut libc::c_char; - type_0 = MAILMIME_DISCRETE_TYPE_ERROR as libc::c_int; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"text\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"text\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_DISCRETE_TYPE_TEXT as libc::c_int - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"image\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"image\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_DISCRETE_TYPE_IMAGE as libc::c_int - } - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"audio\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"audio\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_DISCRETE_TYPE_AUDIO as libc::c_int - } - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"video\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"video\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_DISCRETE_TYPE_VIDEO as libc::c_int - } - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"application\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"application\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_DISCRETE_TYPE_APPLICATION as libc::c_int - } - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailmime_extension_token_parse(message, length, &mut cur_token, &mut extension); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_DISCRETE_TYPE_EXTENSION as libc::c_int - } - } - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - discrete_type = mailmime_discrete_type_new(type_0, extension); - if discrete_type.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - mailmime_extension_token_free(extension); - } else { - *result = discrete_type; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} -unsafe fn mailmime_composite_type_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_composite_type, -) -> libc::c_int { - let mut extension_token: *mut libc::c_char = 0 as *mut libc::c_char; - let mut type_0: libc::c_int = 0; - let mut ct: *mut mailmime_composite_type = 0 as *mut mailmime_composite_type; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - extension_token = 0 as *mut libc::c_char; - type_0 = MAILMIME_COMPOSITE_TYPE_ERROR as libc::c_int; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"message\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"message\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_COMPOSITE_TYPE_MESSAGE as libc::c_int - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"multipart\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"multipart\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_COMPOSITE_TYPE_MULTIPART as libc::c_int - } - } - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - ct = mailmime_composite_type_new(type_0, extension_token); - if ct.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !extension_token.is_null() { - mailmime_extension_token_free(extension_token); - } - } else { - *result = ct; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} - -pub unsafe fn mailmime_description_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - return mailimf_custom_string_parse(message, length, indx, result, Some(is_text)); -} -unsafe fn is_text(mut ch: libc::c_char) -> libc::c_int { - let mut uch: libc::c_uchar = ch as libc::c_uchar; - if (uch as libc::c_int) < 1i32 { - return 0i32; - } - if uch as libc::c_int == 10i32 || uch as libc::c_int == 13i32 { - return 0i32; - } - return 1i32; -} - -pub unsafe fn mailmime_location_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - return mailimf_custom_string_parse(message, length, indx, result, Some(is_text)); -} - -pub unsafe fn mailmime_encoding_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_mechanism, -) -> libc::c_int { - return mailmime_mechanism_parse(message, length, indx, result); -} -unsafe fn mailmime_mechanism_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_mechanism, -) -> libc::c_int { - let mut token: *mut libc::c_char = 0 as *mut libc::c_char; - let mut type_0: libc::c_int = 0; - let mut mechanism: *mut mailmime_mechanism = 0 as *mut mailmime_mechanism; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - cur_token = *indx; - type_0 = MAILMIME_MECHANISM_ERROR as libc::c_int; - token = 0 as *mut libc::c_char; - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"7bit\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"7bit\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_MECHANISM_7BIT as libc::c_int - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"8bit\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"8bit\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_MECHANISM_8BIT as libc::c_int - } - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"binary\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"binary\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_MECHANISM_BINARY as libc::c_int - } - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"quoted-printable\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"quoted-printable\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_MECHANISM_QUOTED_PRINTABLE as libc::c_int - } - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailimf_token_case_insensitive_len_parse( - message, - length, - &mut cur_token, - b"base64\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - strlen(b"base64\x00" as *const u8 as *const libc::c_char), - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_MECHANISM_BASE64 as libc::c_int - } - } - if r == MAILIMF_ERROR_PARSE as libc::c_int { - r = mailmime_token_parse(message, length, &mut cur_token, &mut token); - if r == MAILIMF_NO_ERROR as libc::c_int { - type_0 = MAILMIME_MECHANISM_TOKEN as libc::c_int - } - } - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - mechanism = mailmime_mechanism_new(type_0, token); - if mechanism.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !token.is_null() { - mailmime_token_free(token); - } - } else { - *result = mechanism; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} - -pub unsafe fn mailmime_field_parse( - mut field: *mut mailimf_optional_field, - mut result: *mut *mut mailmime_field, -) -> libc::c_int { - let mut name: *mut libc::c_char = 0 as *mut libc::c_char; - let mut value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut guessed_type: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut content: *mut mailmime_content = 0 as *mut mailmime_content; - let mut encoding: *mut mailmime_mechanism = 0 as *mut mailmime_mechanism; - let mut id: *mut libc::c_char = 0 as *mut libc::c_char; - let mut description: *mut libc::c_char = 0 as *mut libc::c_char; - let mut version: uint32_t = 0; - let mut mime_field: *mut mailmime_field = 0 as *mut mailmime_field; - let mut language: *mut mailmime_language = 0 as *mut mailmime_language; - let mut disposition: *mut mailmime_disposition = 0 as *mut mailmime_disposition; - let mut location: *mut libc::c_char = 0 as *mut libc::c_char; - let mut res: libc::c_int = 0; - let mut r: libc::c_int = 0; - name = (*field).fld_name; - value = (*field).fld_value; - cur_token = 0i32 as size_t; - content = 0 as *mut mailmime_content; - encoding = 0 as *mut mailmime_mechanism; - id = 0 as *mut libc::c_char; - description = 0 as *mut libc::c_char; - version = 0i32 as uint32_t; - disposition = 0 as *mut mailmime_disposition; - language = 0 as *mut mailmime_language; - location = 0 as *mut libc::c_char; - guessed_type = guess_field_type(name); - match guessed_type { - 1 => { - if strcasecmp( - name, - b"Content-Type\x00" as *const u8 as *const libc::c_char, - ) != 0i32 - { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - let mut cur_token_0: size_t = 0i32 as size_t; - let mut decoded_value: *mut libc::c_char = 0 as *mut libc::c_char; - r = mailmime_encoded_phrase_parse( - b"us-ascii\x00" as *const u8 as *const libc::c_char, - value, - strlen(value), - &mut cur_token_0, - b"utf-8\x00" as *const u8 as *const libc::c_char, - &mut decoded_value, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - cur_token_0 = 0i32 as size_t; - r = mailmime_content_parse(value, strlen(value), &mut cur_token_0, &mut content) - } else { - cur_token_0 = 0i32 as size_t; - r = mailmime_content_parse( - decoded_value, - strlen(decoded_value), - &mut cur_token_0, - &mut content, - ); - free(decoded_value as *mut libc::c_void); - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 2 => { - if strcasecmp( - name, - b"Content-Transfer-Encoding\x00" as *const u8 as *const libc::c_char, - ) != 0i32 - { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - r = mailmime_encoding_parse(value, strlen(value), &mut cur_token, &mut encoding); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 3 => { - if strcasecmp(name, b"Content-ID\x00" as *const u8 as *const libc::c_char) != 0i32 { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - r = mailmime_id_parse(value, strlen(value), &mut cur_token, &mut id); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 4 => { - if strcasecmp( - name, - b"Content-Description\x00" as *const u8 as *const libc::c_char, - ) != 0i32 - { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - r = mailmime_description_parse(value, strlen(value), &mut cur_token, &mut description); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 5 => { - if strcasecmp( - name, - b"MIME-Version\x00" as *const u8 as *const libc::c_char, - ) != 0i32 - { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - r = mailmime_version_parse(value, strlen(value), &mut cur_token, &mut version); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 6 => { - if strcasecmp( - name, - b"Content-Disposition\x00" as *const u8 as *const libc::c_char, - ) != 0i32 - { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - r = mailmime_disposition_parse(value, strlen(value), &mut cur_token, &mut disposition); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 7 => { - if strcasecmp( - name, - b"Content-Language\x00" as *const u8 as *const libc::c_char, - ) != 0i32 - { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - r = mailmime_language_parse(value, strlen(value), &mut cur_token, &mut language); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 8 => { - if strcasecmp( - name, - b"Content-Location\x00" as *const u8 as *const libc::c_char, - ) != 0i32 - { - return MAILIMF_ERROR_PARSE as libc::c_int; - } - r = mailmime_location_parse(value, strlen(value), &mut cur_token, &mut location); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - _ => return MAILIMF_ERROR_PARSE as libc::c_int, - } - mime_field = mailmime_field_new( - guessed_type, - content, - encoding, - id, - description, - version, - disposition, - language, - location, - ); - if mime_field.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - if !location.is_null() { - mailmime_location_free(location); - } - if !language.is_null() { - mailmime_language_free(language); - } - if !content.is_null() { - mailmime_content_free(content); - } - if !encoding.is_null() { - mailmime_encoding_free(encoding); - } - if !id.is_null() { - mailmime_id_free(id); - } - if !description.is_null() { - mailmime_description_free(description); - } - return res; - } else { - *result = mime_field; - return MAILIMF_NO_ERROR as libc::c_int; - }; -} - -pub unsafe fn mailmime_language_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut mailmime_language, -) -> libc::c_int { - let mut current_block: u64; - let mut cur_token: size_t = 0; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - let mut list: *mut clist = 0 as *mut clist; - let mut language: *mut mailmime_language = 0 as *mut mailmime_language; - cur_token = *indx; - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - loop { - let mut atom: *mut libc::c_char = 0 as *mut libc::c_char; - r = mailimf_unstrict_char_parse( - message, - length, - &mut cur_token, - ',' as i32 as libc::c_char, - ); - if r == MAILIMF_NO_ERROR as libc::c_int { - r = mailimf_atom_parse(message, length, &mut cur_token, &mut atom); - if r == MAILIMF_NO_ERROR as libc::c_int { - r = clist_insert_after(list, (*list).last, atom as *mut libc::c_void); - if !(r < 0i32) { - continue; - } - mailimf_atom_free(atom); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 14533943604180559553; - break; - } else { - /* do nothing */ - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 6669252993407410313; - break; - } - res = r; - current_block = 11601180562230609130; - break; - } - } else { - /* do nothing */ - if r == MAILIMF_ERROR_PARSE as libc::c_int { - current_block = 6669252993407410313; - break; - } - res = r; - current_block = 11601180562230609130; - break; - } - } - match current_block { - 11601180562230609130 => {} - _ => { - match current_block { - 6669252993407410313 => { - language = mailmime_language_new(list); - if language.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = language; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - _ => {} - } - clist_foreach( - list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailimf_atom_free)), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - } - } - return res; -} - -pub unsafe fn mailmime_version_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut uint32_t, -) -> libc::c_int { - let mut cur_token: size_t = 0; - let mut hi: uint32_t = 0; - let mut low: uint32_t = 0; - let mut version: uint32_t = 0; - let mut r: libc::c_int = 0; - cur_token = *indx; - r = mailimf_number_parse(message, length, &mut cur_token, &mut hi); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_unstrict_char_parse(message, length, &mut cur_token, '.' as i32 as libc::c_char); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_cfws_parse(message, length, &mut cur_token); - if r != MAILIMF_NO_ERROR as libc::c_int && r != MAILIMF_ERROR_PARSE as libc::c_int { - return r; - } - r = mailimf_number_parse(message, length, &mut cur_token, &mut low); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - version = (hi << 16i32).wrapping_add(low); - *result = version; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_id_parse( - mut message: *const libc::c_char, - mut length: size_t, - mut indx: *mut size_t, - mut result: *mut *mut libc::c_char, -) -> libc::c_int { - return mailimf_msg_id_parse(message, length, indx, result); -} -unsafe fn guess_field_type(mut name: *mut libc::c_char) -> libc::c_int { - let mut state: libc::c_int = 0; - if *name as libc::c_int == 'M' as i32 { - return MAILMIME_FIELD_VERSION as libc::c_int; - } - if strncasecmp( - name, - b"Content-\x00" as *const u8 as *const libc::c_char, - 8i32 as libc::size_t, - ) != 0i32 - { - return MAILMIME_FIELD_NONE as libc::c_int; - } - name = name.offset(8isize); - state = FIELD_STATE_START as libc::c_int; - loop { - match state { - 0 => { - match toupper(*name as libc::c_uchar as libc::c_int) as libc::c_char as libc::c_int - { - 84 => state = FIELD_STATE_T as libc::c_int, - 73 => return MAILMIME_FIELD_ID as libc::c_int, - 68 => state = FIELD_STATE_D as libc::c_int, - 76 => state = FIELD_STATE_L as libc::c_int, - _ => return MAILMIME_FIELD_NONE as libc::c_int, - } - } - 1 => { - match toupper(*name as libc::c_uchar as libc::c_int) as libc::c_char as libc::c_int - { - 89 => return MAILMIME_FIELD_TYPE as libc::c_int, - 82 => return MAILMIME_FIELD_TRANSFER_ENCODING as libc::c_int, - _ => return MAILMIME_FIELD_NONE as libc::c_int, - } - } - 2 => { - match toupper(*name as libc::c_uchar as libc::c_int) as libc::c_char as libc::c_int - { - 69 => return MAILMIME_FIELD_DESCRIPTION as libc::c_int, - 73 => return MAILMIME_FIELD_DISPOSITION as libc::c_int, - _ => return MAILMIME_FIELD_NONE as libc::c_int, - } - } - 3 => { - match toupper(*name as libc::c_uchar as libc::c_int) as libc::c_char as libc::c_int - { - 65 => return MAILMIME_FIELD_LANGUAGE as libc::c_int, - 79 => return MAILMIME_FIELD_LOCATION as libc::c_int, - _ => return MAILMIME_FIELD_NONE as libc::c_int, - } - } - _ => {} - } - name = name.offset(1isize) - } -} - -pub unsafe fn mailmime_fields_parse( - mut fields: *mut mailimf_fields, - mut result: *mut *mut mailmime_fields, -) -> libc::c_int { - let mut current_block: u64; - let mut cur: *mut clistiter = 0 as *mut clistiter; - let mut mime_fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - let mut list: *mut clist = 0 as *mut clist; - let mut r: libc::c_int = 0; - let mut res: libc::c_int = 0; - list = clist_new(); - if list.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - cur = (*(*fields).fld_list).first; - loop { - if cur.is_null() { - current_block = 1109700713171191020; - break; - } - let mut field: *mut mailimf_field = 0 as *mut mailimf_field; - let mut mime_field: *mut mailmime_field = 0 as *mut mailmime_field; - field = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailimf_field; - if (*field).fld_type == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int { - r = mailmime_field_parse((*field).fld_data.fld_optional_field, &mut mime_field); - if r == MAILIMF_NO_ERROR as libc::c_int { - r = clist_insert_after(list, (*list).last, mime_field as *mut libc::c_void); - if r < 0i32 { - mailmime_field_free(mime_field); - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 17592539310030730040; - break; - } - } else if !(r == MAILIMF_ERROR_PARSE as libc::c_int) { - /* do nothing */ - res = r; - current_block = 17592539310030730040; - break; - } - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - match current_block { - 1109700713171191020 => { - if (*list).first.is_null() { - res = MAILIMF_ERROR_PARSE as libc::c_int - } else { - mime_fields = mailmime_fields_new(list); - if mime_fields.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = mime_fields; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - _ => {} - } - clist_foreach( - list, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailmime_field_free), - ), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - return res; -} diff --git a/mmime/src/mailmime/types.rs b/mmime/src/mailmime/types.rs deleted file mode 100644 index 7088d3f46..000000000 --- a/mmime/src/mailmime/types.rs +++ /dev/null @@ -1,891 +0,0 @@ -use crate::clist::*; -use crate::mailimf::types::*; -use crate::mmapstring::*; -use crate::other::*; - -pub const MAILMIME_MECHANISM_TOKEN: libc::c_uint = 6; -pub const MAILMIME_MECHANISM_BASE64: libc::c_uint = 5; -pub const MAILMIME_MECHANISM_QUOTED_PRINTABLE: libc::c_uint = 4; -pub const MAILMIME_MECHANISM_BINARY: libc::c_uint = 3; -pub const MAILMIME_MECHANISM_8BIT: libc::c_uint = 2; -pub const MAILMIME_MECHANISM_7BIT: libc::c_uint = 1; -pub const MAILMIME_MECHANISM_ERROR: libc::c_uint = 0; - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_composite_type { - pub ct_type: libc::c_int, - pub ct_token: *mut libc::c_char, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_content { - pub ct_type: *mut mailmime_type, - pub ct_subtype: *mut libc::c_char, - pub ct_parameters: *mut clist, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_type { - pub tp_type: libc::c_int, - pub tp_data: unnamed, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub union unnamed { - pub tp_discrete_type: *mut mailmime_discrete_type, - pub tp_composite_type: *mut mailmime_composite_type, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_discrete_type { - pub dt_type: libc::c_int, - pub dt_extension: *mut libc::c_char, -} -pub type unnamed_0 = libc::c_uint; -pub const MAILMIME_FIELD_LOCATION: unnamed_0 = 8; -pub const MAILMIME_FIELD_LANGUAGE: unnamed_0 = 7; -pub const MAILMIME_FIELD_DISPOSITION: unnamed_0 = 6; -pub const MAILMIME_FIELD_VERSION: unnamed_0 = 5; -pub const MAILMIME_FIELD_DESCRIPTION: unnamed_0 = 4; -pub const MAILMIME_FIELD_ID: unnamed_0 = 3; -pub const MAILMIME_FIELD_TRANSFER_ENCODING: unnamed_0 = 2; -pub const MAILMIME_FIELD_TYPE: unnamed_0 = 1; -pub const MAILMIME_FIELD_NONE: unnamed_0 = 0; -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_field { - pub fld_type: libc::c_int, - pub fld_data: unnamed_1, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub union unnamed_1 { - pub fld_content: *mut mailmime_content, - pub fld_encoding: *mut mailmime_mechanism, - pub fld_id: *mut libc::c_char, - pub fld_description: *mut libc::c_char, - pub fld_version: uint32_t, - pub fld_disposition: *mut mailmime_disposition, - pub fld_language: *mut mailmime_language, - pub fld_location: *mut libc::c_char, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_language { - pub lg_list: *mut clist, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_disposition { - pub dsp_type: *mut mailmime_disposition_type, - pub dsp_parms: *mut clist, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_disposition_type { - pub dsp_type: libc::c_int, - pub dsp_extension: *mut libc::c_char, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_mechanism { - pub enc_type: libc::c_int, - pub enc_token: *mut libc::c_char, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_fields { - pub fld_list: *mut clist, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_parameter { - pub pa_name: *mut libc::c_char, - pub pa_value: *mut libc::c_char, -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_disposition_parm { - pub pa_type: libc::c_int, - pub pa_data: unnamed_3, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub union unnamed_3 { - pub pa_filename: *mut libc::c_char, - pub pa_creation_date: *mut libc::c_char, - pub pa_modification_date: *mut libc::c_char, - pub pa_read_date: *mut libc::c_char, - pub pa_size: size_t, - pub pa_parameter: *mut mailmime_parameter, -} -pub const MAILMIME_DISPOSITION_PARM_PARAMETER: unnamed_11 = 5; -pub const MAILMIME_DISPOSITION_PARM_READ_DATE: unnamed_11 = 3; -pub const MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE: unnamed_11 = 2; -pub const MAILMIME_DISPOSITION_PARM_CREATION_DATE: unnamed_11 = 1; -pub const MAILMIME_DISPOSITION_PARM_FILENAME: unnamed_11 = 0; -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_multipart_body { - pub bd_list: *mut clist, -} -pub type unnamed_4 = libc::c_uint; -pub const MAILMIME_DATA_FILE: unnamed_4 = 1; -pub const MAILMIME_DATA_TEXT: unnamed_4 = 0; -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_data { - pub dt_type: libc::c_int, - pub dt_encoding: libc::c_int, - pub dt_encoded: libc::c_int, - pub dt_data: unnamed_5, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub union unnamed_5 { - pub dt_text: unnamed_6, - pub dt_filename: *mut libc::c_char, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct unnamed_6 { - pub dt_data: *const libc::c_char, - pub dt_length: size_t, -} -pub type unnamed_7 = libc::c_uint; -pub const MAILMIME_MESSAGE: unnamed_7 = 3; -pub const MAILMIME_MULTIPLE: unnamed_7 = 2; -pub const MAILMIME_SINGLE: unnamed_7 = 1; -pub const MAILMIME_NONE: unnamed_7 = 0; - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct Mailmime { - pub mm_parent_type: libc::c_int, - pub mm_parent: *mut Mailmime, - pub mm_multipart_pos: *mut clistiter, - pub mm_type: libc::c_int, - pub mm_mime_start: *const libc::c_char, - pub mm_length: size_t, - pub mm_mime_fields: *mut mailmime_fields, - pub mm_content_type: *mut mailmime_content, - pub mm_body: *mut mailmime_data, - pub mm_data: unnamed_8, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub union unnamed_8 { - pub mm_single: *mut mailmime_data, - pub mm_multipart: unnamed_10, - pub mm_message: unnamed_9, -} -/* message */ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct unnamed_9 { - pub mm_fields: *mut mailimf_fields, - pub mm_msg_mime: *mut Mailmime, -} -/* multi-part */ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct unnamed_10 { - pub mm_preamble: *mut mailmime_data, - pub mm_epilogue: *mut mailmime_data, - pub mm_mp_list: *mut clist, -} -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_encoded_word { - pub wd_charset: *mut libc::c_char, - pub wd_text: *mut libc::c_char, -} -pub type unnamed_11 = libc::c_uint; -pub const MAILMIME_DISPOSITION_PARM_SIZE: unnamed_11 = 4; -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_section { - pub sec_list: *mut clist, -} - -pub unsafe fn mailmime_attribute_free(mut attribute: *mut libc::c_char) { - mailmime_token_free(attribute); -} - -pub unsafe fn mailmime_token_free(mut token: *mut libc::c_char) { - free(token as *mut libc::c_void); -} -pub unsafe fn mailmime_composite_type_new( - mut ct_type: libc::c_int, - mut ct_token: *mut libc::c_char, -) -> *mut mailmime_composite_type { - let mut ct: *mut mailmime_composite_type = 0 as *mut mailmime_composite_type; - ct = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_composite_type; - if ct.is_null() { - return 0 as *mut mailmime_composite_type; - } - (*ct).ct_type = ct_type; - (*ct).ct_token = ct_token; - return ct; -} - -pub unsafe fn mailmime_composite_type_free(mut ct: *mut mailmime_composite_type) { - if !(*ct).ct_token.is_null() { - mailmime_extension_token_free((*ct).ct_token); - } - free(ct as *mut libc::c_void); -} - -pub unsafe fn mailmime_extension_token_free(mut extension: *mut libc::c_char) { - mailmime_token_free(extension); -} - -pub unsafe fn mailmime_content_new( - mut ct_type: *mut mailmime_type, - mut ct_subtype: *mut libc::c_char, - mut ct_parameters: *mut clist, -) -> *mut mailmime_content { - let mut content: *mut mailmime_content = 0 as *mut mailmime_content; - content = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailmime_content; - if content.is_null() { - return 0 as *mut mailmime_content; - } - (*content).ct_type = ct_type; - (*content).ct_subtype = ct_subtype; - (*content).ct_parameters = ct_parameters; - return content; -} - -pub unsafe fn mailmime_content_free(mut content: *mut mailmime_content) { - mailmime_type_free((*content).ct_type); - mailmime_subtype_free((*content).ct_subtype); - if !(*content).ct_parameters.is_null() { - clist_foreach( - (*content).ct_parameters, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailmime_parameter_free), - ), - 0 as *mut libc::c_void, - ); - clist_free((*content).ct_parameters); - } - free(content as *mut libc::c_void); -} - -pub unsafe fn mailmime_parameter_free(mut parameter: *mut mailmime_parameter) { - mailmime_attribute_free((*parameter).pa_name); - mailmime_value_free((*parameter).pa_value); - free(parameter as *mut libc::c_void); -} - -pub unsafe fn mailmime_value_free(mut value: *mut libc::c_char) { - free(value as *mut libc::c_void); -} - -pub unsafe fn mailmime_subtype_free(mut subtype: *mut libc::c_char) { - mailmime_extension_token_free(subtype); -} - -pub unsafe fn mailmime_type_free(mut type_0: *mut mailmime_type) { - match (*type_0).tp_type { - 1 => { - mailmime_discrete_type_free((*type_0).tp_data.tp_discrete_type); - } - 2 => { - mailmime_composite_type_free((*type_0).tp_data.tp_composite_type); - } - _ => {} - } - free(type_0 as *mut libc::c_void); -} - -pub unsafe fn mailmime_discrete_type_free(mut discrete_type: *mut mailmime_discrete_type) { - if !(*discrete_type).dt_extension.is_null() { - mailmime_extension_token_free((*discrete_type).dt_extension); - } - free(discrete_type as *mut libc::c_void); -} - -pub unsafe fn mailmime_description_free(mut description: *mut libc::c_char) { - free(description as *mut libc::c_void); -} - -pub unsafe fn mailmime_location_free(mut location: *mut libc::c_char) { - free(location as *mut libc::c_void); -} - -pub unsafe fn mailmime_discrete_type_new( - mut dt_type: libc::c_int, - mut dt_extension: *mut libc::c_char, -) -> *mut mailmime_discrete_type { - let mut discrete_type: *mut mailmime_discrete_type = 0 as *mut mailmime_discrete_type; - discrete_type = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_discrete_type; - if discrete_type.is_null() { - return 0 as *mut mailmime_discrete_type; - } - (*discrete_type).dt_type = dt_type; - (*discrete_type).dt_extension = dt_extension; - return discrete_type; -} - -pub unsafe fn mailmime_encoding_free(mut encoding: *mut mailmime_mechanism) { - mailmime_mechanism_free(encoding); -} - -pub unsafe fn mailmime_mechanism_free(mut mechanism: *mut mailmime_mechanism) { - if !(*mechanism).enc_token.is_null() { - mailmime_token_free((*mechanism).enc_token); - } - free(mechanism as *mut libc::c_void); -} - -pub unsafe fn mailmime_id_free(mut id: *mut libc::c_char) { - mailimf_msg_id_free(id); -} - -pub unsafe fn mailmime_mechanism_new( - mut enc_type: libc::c_int, - mut enc_token: *mut libc::c_char, -) -> *mut mailmime_mechanism { - let mut mechanism: *mut mailmime_mechanism = 0 as *mut mailmime_mechanism; - mechanism = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_mechanism; - if mechanism.is_null() { - return 0 as *mut mailmime_mechanism; - } - (*mechanism).enc_type = enc_type; - (*mechanism).enc_token = enc_token; - return mechanism; -} - -pub unsafe fn mailmime_parameter_new( - mut pa_name: *mut libc::c_char, - mut pa_value: *mut libc::c_char, -) -> *mut mailmime_parameter { - let mut parameter: *mut mailmime_parameter = 0 as *mut mailmime_parameter; - parameter = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_parameter; - if parameter.is_null() { - return 0 as *mut mailmime_parameter; - } - (*parameter).pa_name = pa_name; - (*parameter).pa_value = pa_value; - return parameter; -} - -pub unsafe fn mailmime_type_new( - mut tp_type: libc::c_int, - mut tp_discrete_type: *mut mailmime_discrete_type, - mut tp_composite_type: *mut mailmime_composite_type, -) -> *mut mailmime_type { - let mut mime_type: *mut mailmime_type = 0 as *mut mailmime_type; - mime_type = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailmime_type; - if mime_type.is_null() { - return 0 as *mut mailmime_type; - } - (*mime_type).tp_type = tp_type; - match tp_type { - 1 => (*mime_type).tp_data.tp_discrete_type = tp_discrete_type, - 2 => (*mime_type).tp_data.tp_composite_type = tp_composite_type, - _ => {} - } - return mime_type; -} - -pub unsafe fn mailmime_language_new(mut lg_list: *mut clist) -> *mut mailmime_language { - let mut lang: *mut mailmime_language = 0 as *mut mailmime_language; - lang = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_language; - if lang.is_null() { - return 0 as *mut mailmime_language; - } - (*lang).lg_list = lg_list; - return lang; -} - -pub unsafe fn mailmime_language_free(mut lang: *mut mailmime_language) { - clist_foreach( - (*lang).lg_list, - ::std::mem::transmute:: ()>, clist_func>(Some( - mailimf_atom_free, - )), - 0 as *mut libc::c_void, - ); - clist_free((*lang).lg_list); - free(lang as *mut libc::c_void); -} -/* -void mailmime_x_token_free(gchar * x_token); -*/ -pub unsafe fn mailmime_field_new( - mut fld_type: libc::c_int, - mut fld_content: *mut mailmime_content, - mut fld_encoding: *mut mailmime_mechanism, - mut fld_id: *mut libc::c_char, - mut fld_description: *mut libc::c_char, - mut fld_version: uint32_t, - mut fld_disposition: *mut mailmime_disposition, - mut fld_language: *mut mailmime_language, - mut fld_location: *mut libc::c_char, -) -> *mut mailmime_field { - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - field = malloc(::std::mem::size_of::() as libc::size_t) as *mut mailmime_field; - if field.is_null() { - return 0 as *mut mailmime_field; - } - (*field).fld_type = fld_type; - match fld_type { - 1 => (*field).fld_data.fld_content = fld_content, - 2 => (*field).fld_data.fld_encoding = fld_encoding, - 3 => (*field).fld_data.fld_id = fld_id, - 4 => (*field).fld_data.fld_description = fld_description, - 5 => (*field).fld_data.fld_version = fld_version, - 6 => (*field).fld_data.fld_disposition = fld_disposition, - 7 => (*field).fld_data.fld_language = fld_language, - 8 => (*field).fld_data.fld_location = fld_location, - _ => {} - } - return field; -} - -pub unsafe fn mailmime_field_free(mut field: *mut mailmime_field) { - match (*field).fld_type { - 1 => { - if !(*field).fld_data.fld_content.is_null() { - mailmime_content_free((*field).fld_data.fld_content); - } - } - 2 => { - if !(*field).fld_data.fld_encoding.is_null() { - mailmime_encoding_free((*field).fld_data.fld_encoding); - } - } - 3 => { - if !(*field).fld_data.fld_id.is_null() { - mailmime_id_free((*field).fld_data.fld_id); - } - } - 4 => { - if !(*field).fld_data.fld_description.is_null() { - mailmime_description_free((*field).fld_data.fld_description); - } - } - 6 => { - if !(*field).fld_data.fld_disposition.is_null() { - mailmime_disposition_free((*field).fld_data.fld_disposition); - } - } - 7 => { - if !(*field).fld_data.fld_language.is_null() { - mailmime_language_free((*field).fld_data.fld_language); - } - } - 8 => { - if !(*field).fld_data.fld_location.is_null() { - mailmime_location_free((*field).fld_data.fld_location); - } - } - _ => {} - } - free(field as *mut libc::c_void); -} - -pub unsafe fn mailmime_disposition_free(mut dsp: *mut mailmime_disposition) { - mailmime_disposition_type_free((*dsp).dsp_type); - clist_foreach( - (*dsp).dsp_parms, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailmime_disposition_parm_free)), - 0 as *mut libc::c_void, - ); - clist_free((*dsp).dsp_parms); - free(dsp as *mut libc::c_void); -} - -pub unsafe fn mailmime_disposition_parm_free(mut dsp_parm: *mut mailmime_disposition_parm) { - match (*dsp_parm).pa_type { - 0 => { - mailmime_filename_parm_free((*dsp_parm).pa_data.pa_filename); - } - 1 => { - mailmime_creation_date_parm_free((*dsp_parm).pa_data.pa_creation_date); - } - 2 => { - mailmime_modification_date_parm_free((*dsp_parm).pa_data.pa_modification_date); - } - 3 => { - mailmime_read_date_parm_free((*dsp_parm).pa_data.pa_read_date); - } - 5 => { - mailmime_parameter_free((*dsp_parm).pa_data.pa_parameter); - } - _ => {} - } - free(dsp_parm as *mut libc::c_void); -} - -pub unsafe fn mailmime_read_date_parm_free(mut date: *mut libc::c_char) { - mailmime_quoted_date_time_free(date); -} - -pub unsafe fn mailmime_quoted_date_time_free(mut date: *mut libc::c_char) { - mailimf_quoted_string_free(date); -} - -pub unsafe fn mailmime_modification_date_parm_free(mut date: *mut libc::c_char) { - mailmime_quoted_date_time_free(date); -} - -pub unsafe fn mailmime_creation_date_parm_free(mut date: *mut libc::c_char) { - mailmime_quoted_date_time_free(date); -} - -pub unsafe fn mailmime_filename_parm_free(mut filename: *mut libc::c_char) { - mailmime_value_free(filename); -} - -pub unsafe fn mailmime_disposition_type_free(mut dsp_type: *mut mailmime_disposition_type) { - if !(*dsp_type).dsp_extension.is_null() { - free((*dsp_type).dsp_extension as *mut libc::c_void); - } - free(dsp_type as *mut libc::c_void); -} - -pub unsafe fn mailmime_fields_new(mut fld_list: *mut clist) -> *mut mailmime_fields { - let mut fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - fields = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailmime_fields; - if fields.is_null() { - return 0 as *mut mailmime_fields; - } - (*fields).fld_list = fld_list; - return fields; -} - -pub unsafe fn mailmime_fields_free(mut fields: *mut mailmime_fields) { - clist_foreach( - (*fields).fld_list, - ::std::mem::transmute:: ()>, clist_func>(Some( - mailmime_field_free, - )), - 0 as *mut libc::c_void, - ); - clist_free((*fields).fld_list); - free(fields as *mut libc::c_void); -} - -pub unsafe fn mailmime_multipart_body_new(mut bd_list: *mut clist) -> *mut mailmime_multipart_body { - let mut mp_body: *mut mailmime_multipart_body = 0 as *mut mailmime_multipart_body; - mp_body = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_multipart_body; - if mp_body.is_null() { - return 0 as *mut mailmime_multipart_body; - } - (*mp_body).bd_list = bd_list; - return mp_body; -} - -pub unsafe fn mailmime_multipart_body_free(mut mp_body: *mut mailmime_multipart_body) { - clist_foreach( - (*mp_body).bd_list, - ::std::mem::transmute:: ()>, clist_func>(Some( - mailimf_body_free, - )), - 0 as *mut libc::c_void, - ); - clist_free((*mp_body).bd_list); - free(mp_body as *mut libc::c_void); -} - -pub unsafe fn mailmime_data_new( - mut dt_type: libc::c_int, - mut dt_encoding: libc::c_int, - mut dt_encoded: libc::c_int, - mut dt_data: *const libc::c_char, - mut dt_length: size_t, - mut dt_filename: *mut libc::c_char, -) -> *mut mailmime_data { - let mut mime_data: *mut mailmime_data = 0 as *mut mailmime_data; - mime_data = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailmime_data; - if mime_data.is_null() { - return 0 as *mut mailmime_data; - } - (*mime_data).dt_type = dt_type; - (*mime_data).dt_encoding = dt_encoding; - (*mime_data).dt_encoded = dt_encoded; - match dt_type { - 0 => { - (*mime_data).dt_data.dt_text.dt_data = dt_data; - (*mime_data).dt_data.dt_text.dt_length = dt_length - } - 1 => (*mime_data).dt_data.dt_filename = dt_filename, - _ => {} - } - return mime_data; -} - -pub unsafe fn mailmime_data_free(mut mime_data: *mut mailmime_data) { - match (*mime_data).dt_type { - 1 => { - free((*mime_data).dt_data.dt_filename as *mut libc::c_void); - } - _ => {} - } - free(mime_data as *mut libc::c_void); -} - -pub unsafe fn mailmime_new( - mut mm_type: libc::c_int, - mut mm_mime_start: *const libc::c_char, - mut mm_length: size_t, - mut mm_mime_fields: *mut mailmime_fields, - mut mm_content_type: *mut mailmime_content, - mut mm_body: *mut mailmime_data, - mut mm_preamble: *mut mailmime_data, - mut mm_epilogue: *mut mailmime_data, - mut mm_mp_list: *mut clist, - mut mm_fields: *mut mailimf_fields, - mut mm_msg_mime: *mut Mailmime, -) -> *mut Mailmime { - let mut mime: *mut Mailmime = 0 as *mut Mailmime; - let mut cur: *mut clistiter = 0 as *mut clistiter; - mime = malloc(::std::mem::size_of::() as libc::size_t) as *mut Mailmime; - if mime.is_null() { - return 0 as *mut Mailmime; - } - (*mime).mm_parent = 0 as *mut Mailmime; - (*mime).mm_parent_type = MAILMIME_NONE as libc::c_int; - (*mime).mm_multipart_pos = 0 as *mut clistiter; - (*mime).mm_type = mm_type; - (*mime).mm_mime_start = mm_mime_start; - (*mime).mm_length = mm_length; - (*mime).mm_mime_fields = mm_mime_fields; - (*mime).mm_content_type = mm_content_type; - (*mime).mm_body = mm_body; - match mm_type { - 1 => (*mime).mm_data.mm_single = mm_body, - 2 => { - (*mime).mm_data.mm_multipart.mm_preamble = mm_preamble; - (*mime).mm_data.mm_multipart.mm_epilogue = mm_epilogue; - (*mime).mm_data.mm_multipart.mm_mp_list = mm_mp_list; - cur = (*mm_mp_list).first; - while !cur.is_null() { - let mut submime: *mut Mailmime = 0 as *mut Mailmime; - submime = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut Mailmime; - (*submime).mm_parent = mime; - (*submime).mm_parent_type = MAILMIME_MULTIPLE as libc::c_int; - (*submime).mm_multipart_pos = cur; - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - } - 3 => { - (*mime).mm_data.mm_message.mm_fields = mm_fields; - (*mime).mm_data.mm_message.mm_msg_mime = mm_msg_mime; - if !mm_msg_mime.is_null() { - (*mm_msg_mime).mm_parent = mime; - (*mm_msg_mime).mm_parent_type = MAILMIME_MESSAGE as libc::c_int - } - } - _ => {} - } - return mime; -} - -pub unsafe fn mailmime_new_simple( - mut mm_type: libc::c_int, - mut mm_mime_fields: *mut mailmime_fields, - mut mm_content_type: *mut mailmime_content, - mut mm_fields: *mut mailimf_fields, - mut mm_msg_mime: *mut Mailmime, -) -> *mut Mailmime { - mailmime_new( - mm_type, - std::ptr::null(), - 0, - mm_mime_fields, - mm_content_type, - std::ptr::null_mut(), - std::ptr::null_mut(), - std::ptr::null_mut(), - std::ptr::null_mut(), - mm_fields, - mm_msg_mime, - ) -} - -pub unsafe fn mailmime_free(mut mime: *mut Mailmime) { - match (*mime).mm_type { - 1 => { - if (*mime).mm_body.is_null() && !(*mime).mm_data.mm_single.is_null() { - mailmime_data_free((*mime).mm_data.mm_single); - } - } - 2 => { - /* do nothing */ - if !(*mime).mm_data.mm_multipart.mm_preamble.is_null() { - mailmime_data_free((*mime).mm_data.mm_multipart.mm_preamble); - } - if !(*mime).mm_data.mm_multipart.mm_epilogue.is_null() { - mailmime_data_free((*mime).mm_data.mm_multipart.mm_epilogue); - } - clist_foreach( - (*mime).mm_data.mm_multipart.mm_mp_list, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailmime_free), - ), - 0 as *mut libc::c_void, - ); - clist_free((*mime).mm_data.mm_multipart.mm_mp_list); - } - 3 => { - if !(*mime).mm_data.mm_message.mm_fields.is_null() { - mailimf_fields_free((*mime).mm_data.mm_message.mm_fields); - } - if !(*mime).mm_data.mm_message.mm_msg_mime.is_null() { - mailmime_free((*mime).mm_data.mm_message.mm_msg_mime); - } - } - _ => {} - } - if !(*mime).mm_body.is_null() { - mailmime_data_free((*mime).mm_body); - } - if !(*mime).mm_mime_fields.is_null() { - mailmime_fields_free((*mime).mm_mime_fields); - } - if !(*mime).mm_content_type.is_null() { - mailmime_content_free((*mime).mm_content_type); - } - free(mime as *mut libc::c_void); -} - -pub unsafe fn mailmime_encoded_word_new( - mut wd_charset: *mut libc::c_char, - mut wd_text: *mut libc::c_char, -) -> *mut mailmime_encoded_word { - let mut ew: *mut mailmime_encoded_word = 0 as *mut mailmime_encoded_word; - ew = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_encoded_word; - if ew.is_null() { - return 0 as *mut mailmime_encoded_word; - } - (*ew).wd_charset = wd_charset; - (*ew).wd_text = wd_text; - return ew; -} - -pub unsafe fn mailmime_encoded_word_free(mut ew: *mut mailmime_encoded_word) { - mailmime_charset_free((*ew).wd_charset); - mailmime_encoded_text_free((*ew).wd_text); - free(ew as *mut libc::c_void); -} - -pub unsafe fn mailmime_encoded_text_free(mut text: *mut libc::c_char) { - free(text as *mut libc::c_void); -} - -pub unsafe fn mailmime_charset_free(mut charset: *mut libc::c_char) { - free(charset as *mut libc::c_void); -} - -pub unsafe fn mailmime_disposition_new( - mut dsp_type: *mut mailmime_disposition_type, - mut dsp_parms: *mut clist, -) -> *mut mailmime_disposition { - let mut dsp: *mut mailmime_disposition = 0 as *mut mailmime_disposition; - dsp = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_disposition; - if dsp.is_null() { - return 0 as *mut mailmime_disposition; - } - (*dsp).dsp_type = dsp_type; - (*dsp).dsp_parms = dsp_parms; - return dsp; -} - -pub unsafe fn mailmime_disposition_type_new( - mut dsp_type: libc::c_int, - mut dsp_extension: *mut libc::c_char, -) -> *mut mailmime_disposition_type { - let mut m_dsp_type: *mut mailmime_disposition_type = 0 as *mut mailmime_disposition_type; - m_dsp_type = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_disposition_type; - if m_dsp_type.is_null() { - return 0 as *mut mailmime_disposition_type; - } - (*m_dsp_type).dsp_type = dsp_type; - (*m_dsp_type).dsp_extension = dsp_extension; - return m_dsp_type; -} - -pub unsafe fn mailmime_disposition_parm_new( - mut pa_type: libc::c_int, - mut pa_filename: *mut libc::c_char, - mut pa_creation_date: *mut libc::c_char, - mut pa_modification_date: *mut libc::c_char, - mut pa_read_date: *mut libc::c_char, - mut pa_size: size_t, - mut pa_parameter: *mut mailmime_parameter, -) -> *mut mailmime_disposition_parm { - let mut dsp_parm: *mut mailmime_disposition_parm = 0 as *mut mailmime_disposition_parm; - dsp_parm = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_disposition_parm; - if dsp_parm.is_null() { - return 0 as *mut mailmime_disposition_parm; - } - (*dsp_parm).pa_type = pa_type; - match pa_type { - 0 => (*dsp_parm).pa_data.pa_filename = pa_filename, - 1 => (*dsp_parm).pa_data.pa_creation_date = pa_creation_date, - 2 => (*dsp_parm).pa_data.pa_modification_date = pa_modification_date, - 3 => (*dsp_parm).pa_data.pa_read_date = pa_read_date, - 4 => (*dsp_parm).pa_data.pa_size = pa_size, - 5 => (*dsp_parm).pa_data.pa_parameter = pa_parameter, - _ => {} - } - return dsp_parm; -} - -pub unsafe fn mailmime_section_new(mut sec_list: *mut clist) -> *mut mailmime_section { - let mut section: *mut mailmime_section = 0 as *mut mailmime_section; - section = - malloc(::std::mem::size_of::() as libc::size_t) as *mut mailmime_section; - if section.is_null() { - return 0 as *mut mailmime_section; - } - (*section).sec_list = sec_list; - return section; -} - -pub unsafe fn mailmime_section_free(mut section: *mut mailmime_section) { - clist_foreach( - (*section).sec_list, - ::std::mem::transmute:: ()>, clist_func>( - Some(free), - ), - 0 as *mut libc::c_void, - ); - clist_free((*section).sec_list); - free(section as *mut libc::c_void); -} - -pub unsafe fn mailmime_decoded_part_free(mut part: *mut libc::c_char) { - mmap_string_unref(part); -} diff --git a/mmime/src/mailmime/types_helper.rs b/mmime/src/mailmime/types_helper.rs deleted file mode 100644 index 630c849f6..000000000 --- a/mmime/src/mailmime/types_helper.rs +++ /dev/null @@ -1,1445 +0,0 @@ -use rand::{thread_rng, Rng}; - -use crate::clist::*; -use crate::mailimf::types::*; -use crate::mailmime::types::*; -use crate::mailmime::*; -use crate::other::*; - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailmime_single_fields { - pub fld_content: *mut mailmime_content, - pub fld_content_charset: *mut libc::c_char, - pub fld_content_boundary: *mut libc::c_char, - pub fld_content_name: *mut libc::c_char, - pub fld_encoding: *mut mailmime_mechanism, - pub fld_id: *mut libc::c_char, - pub fld_description: *mut libc::c_char, - pub fld_version: uint32_t, - pub fld_disposition: *mut mailmime_disposition, - pub fld_disposition_filename: *mut libc::c_char, - pub fld_disposition_creation_date: *mut libc::c_char, - pub fld_disposition_modification_date: *mut libc::c_char, - pub fld_disposition_read_date: *mut libc::c_char, - pub fld_disposition_size: size_t, - pub fld_language: *mut mailmime_language, - pub fld_location: *mut libc::c_char, -} - -pub unsafe fn mailmime_transfer_encoding_get(mut fields: *mut mailmime_fields) -> libc::c_int { - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*fields).fld_list).first; - while !cur.is_null() { - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - field = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailmime_field; - if (*field).fld_type == MAILMIME_FIELD_TRANSFER_ENCODING as libc::c_int { - return (*(*field).fld_data.fld_encoding).enc_type; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - return MAILMIME_MECHANISM_8BIT as libc::c_int; -} - -pub unsafe fn mailmime_disposition_new_filename( - mut type_0: libc::c_int, - mut filename: *mut libc::c_char, -) -> *mut mailmime_disposition { - return mailmime_disposition_new_with_data( - type_0, - filename, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - -1i32 as size_t, - ); -} - -pub unsafe fn mailmime_disposition_new_with_data( - mut type_0: libc::c_int, - mut filename: *mut libc::c_char, - mut creation_date: *mut libc::c_char, - mut modification_date: *mut libc::c_char, - mut read_date: *mut libc::c_char, - mut size: size_t, -) -> *mut mailmime_disposition { - let mut current_block: u64; - let mut dsp_type: *mut mailmime_disposition_type = 0 as *mut mailmime_disposition_type; - let mut list: *mut clist = 0 as *mut clist; - let mut r: libc::c_int = 0; - let mut parm: *mut mailmime_disposition_parm = 0 as *mut mailmime_disposition_parm; - let mut dsp: *mut mailmime_disposition = 0 as *mut mailmime_disposition; - dsp_type = mailmime_disposition_type_new(type_0, 0 as *mut libc::c_char); - if !dsp_type.is_null() { - list = clist_new(); - if !list.is_null() { - if !filename.is_null() { - parm = mailmime_disposition_parm_new( - MAILMIME_DISPOSITION_PARM_FILENAME as libc::c_int, - filename, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0i32 as size_t, - 0 as *mut mailmime_parameter, - ); - if parm.is_null() { - current_block = 13210718484351940574; - } else { - r = clist_insert_after(list, (*list).last, parm as *mut libc::c_void); - if r < 0i32 { - mailmime_disposition_parm_free(parm); - current_block = 13210718484351940574; - } else { - current_block = 4166486009154926805; - } - } - } else { - current_block = 4166486009154926805; - } - match current_block { - 4166486009154926805 => { - if !creation_date.is_null() { - parm = mailmime_disposition_parm_new( - MAILMIME_DISPOSITION_PARM_CREATION_DATE as libc::c_int, - 0 as *mut libc::c_char, - creation_date, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0i32 as size_t, - 0 as *mut mailmime_parameter, - ); - if parm.is_null() { - current_block = 13210718484351940574; - } else { - r = clist_insert_after(list, (*list).last, parm as *mut libc::c_void); - if r < 0i32 { - mailmime_disposition_parm_free(parm); - current_block = 13210718484351940574; - } else { - current_block = 12147880666119273379; - } - } - } else { - current_block = 12147880666119273379; - } - match current_block { - 13210718484351940574 => {} - _ => { - if !modification_date.is_null() { - parm = mailmime_disposition_parm_new( - MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE as libc::c_int, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - modification_date, - 0 as *mut libc::c_char, - 0i32 as size_t, - 0 as *mut mailmime_parameter, - ); - if parm.is_null() { - current_block = 13210718484351940574; - } else { - r = clist_insert_after( - list, - (*list).last, - parm as *mut libc::c_void, - ); - if r < 0i32 { - mailmime_disposition_parm_free(parm); - current_block = 13210718484351940574; - } else { - current_block = 13550086250199790493; - } - } - } else { - current_block = 13550086250199790493; - } - match current_block { - 13210718484351940574 => {} - _ => { - if !read_date.is_null() { - parm = mailmime_disposition_parm_new( - MAILMIME_DISPOSITION_PARM_READ_DATE as libc::c_int, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - read_date, - 0i32 as size_t, - 0 as *mut mailmime_parameter, - ); - if parm.is_null() { - current_block = 13210718484351940574; - } else { - r = clist_insert_after( - list, - (*list).last, - parm as *mut libc::c_void, - ); - if r < 0i32 { - mailmime_disposition_parm_free(parm); - current_block = 13210718484351940574; - } else { - current_block = 9520865839495247062; - } - } - } else { - current_block = 9520865839495247062; - } - match current_block { - 13210718484351940574 => {} - _ => { - if size != -1i32 as size_t { - parm = mailmime_disposition_parm_new( - MAILMIME_DISPOSITION_PARM_SIZE as libc::c_int, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - size, - 0 as *mut mailmime_parameter, - ); - if parm.is_null() { - current_block = 13210718484351940574; - } else { - r = clist_insert_after( - list, - (*list).last, - parm as *mut libc::c_void, - ); - if r < 0i32 { - mailmime_disposition_parm_free(parm); - current_block = 13210718484351940574; - } else { - current_block = 12199444798915819164; - } - } - } else { - current_block = 12199444798915819164; - } - match current_block { - 13210718484351940574 => {} - _ => { - dsp = mailmime_disposition_new(dsp_type, list); - return dsp; - } - } - } - } - } - } - } - } - } - _ => {} - } - clist_foreach( - list, - ::std::mem::transmute::< - Option ()>, - clist_func, - >(Some(mailmime_disposition_parm_free)), - 0 as *mut libc::c_void, - ); - clist_free(list); - } - mailmime_disposition_type_free(dsp_type); - } - return 0 as *mut mailmime_disposition; -} - -pub unsafe fn mailmime_fields_new_empty() -> *mut mailmime_fields { - let mut list: *mut clist = 0 as *mut clist; - let mut fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - list = clist_new(); - if !list.is_null() { - fields = mailmime_fields_new(list); - if fields.is_null() { - clist_free(list); - } else { - return fields; - } - } - return 0 as *mut mailmime_fields; -} - -pub unsafe fn mailmime_fields_add( - mut fields: *mut mailmime_fields, - mut field: *mut mailmime_field, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = clist_insert_after( - (*fields).fld_list, - (*(*fields).fld_list).last, - field as *mut libc::c_void, - ); - if r < 0i32 { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_fields_new_with_data( - mut encoding: *mut mailmime_mechanism, - mut id: *mut libc::c_char, - mut description: *mut libc::c_char, - mut disposition: *mut mailmime_disposition, - mut language: *mut mailmime_language, -) -> *mut mailmime_fields { - let mut current_block: u64; - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - let mut fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - let mut r: libc::c_int = 0; - fields = mailmime_fields_new_empty(); - if !fields.is_null() { - if !encoding.is_null() { - field = mailmime_field_new( - MAILMIME_FIELD_TRANSFER_ENCODING as libc::c_int, - 0 as *mut mailmime_content, - encoding, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0i32 as uint32_t, - 0 as *mut mailmime_disposition, - 0 as *mut mailmime_language, - 0 as *mut libc::c_char, - ); - if field.is_null() { - current_block = 5039974454013832799; - } else { - r = mailmime_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - mailmime_field_detach(field); - mailmime_field_free(field); - current_block = 5039974454013832799; - } else { - current_block = 7746791466490516765; - } - } - } else { - current_block = 7746791466490516765; - } - match current_block { - 7746791466490516765 => { - if !id.is_null() { - field = mailmime_field_new( - MAILMIME_FIELD_ID as libc::c_int, - 0 as *mut mailmime_content, - 0 as *mut mailmime_mechanism, - id, - 0 as *mut libc::c_char, - 0i32 as uint32_t, - 0 as *mut mailmime_disposition, - 0 as *mut mailmime_language, - 0 as *mut libc::c_char, - ); - if field.is_null() { - current_block = 5039974454013832799; - } else { - r = mailmime_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - mailmime_field_detach(field); - mailmime_field_free(field); - current_block = 5039974454013832799; - } else { - current_block = 13242334135786603907; - } - } - } else { - current_block = 13242334135786603907; - } - match current_block { - 5039974454013832799 => {} - _ => { - if !description.is_null() { - field = mailmime_field_new( - MAILMIME_FIELD_DESCRIPTION as libc::c_int, - 0 as *mut mailmime_content, - 0 as *mut mailmime_mechanism, - 0 as *mut libc::c_char, - description, - 0i32 as uint32_t, - 0 as *mut mailmime_disposition, - 0 as *mut mailmime_language, - 0 as *mut libc::c_char, - ); - if field.is_null() { - current_block = 5039974454013832799; - } else { - r = mailmime_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - mailmime_field_detach(field); - mailmime_field_free(field); - current_block = 5039974454013832799; - } else { - current_block = 15125582407903384992; - } - } - } else { - current_block = 15125582407903384992; - } - match current_block { - 5039974454013832799 => {} - _ => { - if !disposition.is_null() { - field = mailmime_field_new( - MAILMIME_FIELD_DISPOSITION as libc::c_int, - 0 as *mut mailmime_content, - 0 as *mut mailmime_mechanism, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0i32 as uint32_t, - disposition, - 0 as *mut mailmime_language, - 0 as *mut libc::c_char, - ); - if field.is_null() { - current_block = 5039974454013832799; - } else { - r = mailmime_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - mailmime_field_detach(field); - mailmime_field_free(field); - current_block = 5039974454013832799; - } else { - current_block = 9520865839495247062; - } - } - } else { - current_block = 9520865839495247062; - } - match current_block { - 5039974454013832799 => {} - _ => { - if !language.is_null() { - field = mailmime_field_new( - MAILMIME_FIELD_DISPOSITION as libc::c_int, - 0 as *mut mailmime_content, - 0 as *mut mailmime_mechanism, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0i32 as uint32_t, - 0 as *mut mailmime_disposition, - language, - 0 as *mut libc::c_char, - ); - if field.is_null() { - current_block = 5039974454013832799; - } else { - r = mailmime_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - mailmime_field_detach(field); - mailmime_field_free(field); - current_block = 5039974454013832799; - } else { - current_block = 15512526488502093901; - } - } - } else { - current_block = 15512526488502093901; - } - match current_block { - 5039974454013832799 => {} - _ => return fields, - } - } - } - } - } - } - } - } - _ => {} - } - clist_foreach( - (*fields).fld_list, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailmime_field_detach), - ), - 0 as *mut libc::c_void, - ); - mailmime_fields_free(fields); - } - return 0 as *mut mailmime_fields; -} -unsafe fn mailmime_field_detach(mut field: *mut mailmime_field) { - match (*field).fld_type { - 1 => (*field).fld_data.fld_content = 0 as *mut mailmime_content, - 2 => (*field).fld_data.fld_encoding = 0 as *mut mailmime_mechanism, - 3 => (*field).fld_data.fld_id = 0 as *mut libc::c_char, - 4 => (*field).fld_data.fld_description = 0 as *mut libc::c_char, - 6 => (*field).fld_data.fld_disposition = 0 as *mut mailmime_disposition, - 7 => (*field).fld_data.fld_language = 0 as *mut mailmime_language, - _ => {} - }; -} - -pub unsafe fn mailmime_fields_new_with_version( - mut encoding: *mut mailmime_mechanism, - mut id: *mut libc::c_char, - mut description: *mut libc::c_char, - mut disposition: *mut mailmime_disposition, - mut language: *mut mailmime_language, -) -> *mut mailmime_fields { - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - let mut fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - let mut r: libc::c_int = 0; - fields = mailmime_fields_new_with_data(encoding, id, description, disposition, language); - if !fields.is_null() { - field = mailmime_field_new( - MAILMIME_FIELD_VERSION as libc::c_int, - 0 as *mut mailmime_content, - 0 as *mut mailmime_mechanism, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - (1i32 << 16i32) as uint32_t, - 0 as *mut mailmime_disposition, - 0 as *mut mailmime_language, - 0 as *mut libc::c_char, - ); - if !field.is_null() { - r = mailmime_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - mailmime_field_detach(field); - mailmime_field_free(field); - } else { - return fields; - } - } - clist_foreach( - (*fields).fld_list, - ::std::mem::transmute:: ()>, clist_func>( - Some(mailmime_field_detach), - ), - 0 as *mut libc::c_void, - ); - mailmime_fields_free(fields); - } - return 0 as *mut mailmime_fields; -} - -pub unsafe fn mailmime_get_content_message() -> *mut mailmime_content { - let mut list: *mut clist = 0 as *mut clist; - let mut composite_type: *mut mailmime_composite_type = 0 as *mut mailmime_composite_type; - let mut mime_type: *mut mailmime_type = 0 as *mut mailmime_type; - let mut content: *mut mailmime_content = 0 as *mut mailmime_content; - let mut subtype: *mut libc::c_char = 0 as *mut libc::c_char; - composite_type = mailmime_composite_type_new( - MAILMIME_COMPOSITE_TYPE_MESSAGE as libc::c_int, - 0 as *mut libc::c_char, - ); - if !composite_type.is_null() { - mime_type = mailmime_type_new( - MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int, - 0 as *mut mailmime_discrete_type, - composite_type, - ); - if !mime_type.is_null() { - composite_type = 0 as *mut mailmime_composite_type; - list = clist_new(); - if !list.is_null() { - subtype = strdup(b"rfc822\x00" as *const u8 as *const libc::c_char); - if !subtype.is_null() { - content = mailmime_content_new(mime_type, subtype, list); - if content.is_null() { - free(subtype as *mut libc::c_void); - } else { - return content; - } - } - clist_free(list); - } - mailmime_type_free(mime_type); - } - if !composite_type.is_null() { - mailmime_composite_type_free(composite_type); - } - } - return 0 as *mut mailmime_content; -} - -pub unsafe fn mailmime_get_content_text() -> *mut mailmime_content { - let mut list: *mut clist = 0 as *mut clist; - let mut discrete_type: *mut mailmime_discrete_type = 0 as *mut mailmime_discrete_type; - let mut mime_type: *mut mailmime_type = 0 as *mut mailmime_type; - let mut content: *mut mailmime_content = 0 as *mut mailmime_content; - let mut subtype: *mut libc::c_char = 0 as *mut libc::c_char; - discrete_type = mailmime_discrete_type_new( - MAILMIME_DISCRETE_TYPE_TEXT as libc::c_int, - 0 as *mut libc::c_char, - ); - if !discrete_type.is_null() { - mime_type = mailmime_type_new( - MAILMIME_TYPE_DISCRETE_TYPE as libc::c_int, - discrete_type, - 0 as *mut mailmime_composite_type, - ); - if !mime_type.is_null() { - discrete_type = 0 as *mut mailmime_discrete_type; - list = clist_new(); - if !list.is_null() { - subtype = strdup(b"plain\x00" as *const u8 as *const libc::c_char); - if !subtype.is_null() { - content = mailmime_content_new(mime_type, subtype, list); - if content.is_null() { - free(subtype as *mut libc::c_void); - } else { - return content; - } - } - clist_free(list); - } - mailmime_type_free(mime_type); - } - if !discrete_type.is_null() { - mailmime_discrete_type_free(discrete_type); - } - } - return 0 as *mut mailmime_content; -} -/* struct mailmime_content * mailmime_get_content(char * mime_type); */ -pub unsafe fn mailmime_data_new_data( - mut encoding: libc::c_int, - mut encoded: libc::c_int, - mut data: *const libc::c_char, - mut length: size_t, -) -> *mut mailmime_data { - return mailmime_data_new( - MAILMIME_DATA_TEXT as libc::c_int, - encoding, - encoded, - data, - length, - 0 as *mut libc::c_char, - ); -} - -pub unsafe fn mailmime_data_new_file( - mut encoding: libc::c_int, - mut encoded: libc::c_int, - mut filename: *mut libc::c_char, -) -> *mut mailmime_data { - return mailmime_data_new( - MAILMIME_DATA_FILE as libc::c_int, - encoding, - encoded, - 0 as *const libc::c_char, - 0i32 as size_t, - filename, - ); -} - -pub unsafe fn mailmime_new_message_data(mut msg_mime: *mut Mailmime) -> *mut Mailmime { - let mut content: *mut mailmime_content = 0 as *mut mailmime_content; - let mut build_info: *mut Mailmime = 0 as *mut Mailmime; - let mut mime_fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - content = mailmime_get_content_message(); - if !content.is_null() { - mime_fields = mailmime_fields_new_with_version( - 0 as *mut mailmime_mechanism, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0 as *mut mailmime_disposition, - 0 as *mut mailmime_language, - ); - if !mime_fields.is_null() { - build_info = mailmime_new( - MAILMIME_MESSAGE as libc::c_int, - 0 as *const libc::c_char, - 0i32 as size_t, - mime_fields, - content, - 0 as *mut mailmime_data, - 0 as *mut mailmime_data, - 0 as *mut mailmime_data, - 0 as *mut clist, - 0 as *mut mailimf_fields, - msg_mime, - ); - if build_info.is_null() { - mailmime_fields_free(mime_fields); - } else { - return build_info; - } - } - mailmime_content_free(content); - } - return 0 as *mut Mailmime; -} - -pub unsafe fn mailmime_new_empty( - mut content: *mut mailmime_content, - mut mime_fields: *mut mailmime_fields, -) -> *mut Mailmime { - let mut current_block: u64; - let mut build_info: *mut Mailmime = 0 as *mut Mailmime; - let mut list: *mut clist = 0 as *mut clist; - let mut r: libc::c_int = 0; - let mut mime_type: libc::c_int = 0; - list = 0 as *mut clist; - match (*(*content).ct_type).tp_type { - 1 => { - mime_type = MAILMIME_SINGLE as libc::c_int; - current_block = 12349973810996921269; - } - 2 => match (*(*(*content).ct_type).tp_data.tp_composite_type).ct_type { - 2 => { - current_block = 5822726848290245908; - match current_block { - 565197971715936940 => { - if strcasecmp( - (*content).ct_subtype, - b"rfc822\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - mime_type = MAILMIME_MESSAGE as libc::c_int - } else { - mime_type = MAILMIME_SINGLE as libc::c_int - } - } - _ => mime_type = MAILMIME_MULTIPLE as libc::c_int, - } - current_block = 12349973810996921269; - } - 1 => { - current_block = 565197971715936940; - match current_block { - 565197971715936940 => { - if strcasecmp( - (*content).ct_subtype, - b"rfc822\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - mime_type = MAILMIME_MESSAGE as libc::c_int - } else { - mime_type = MAILMIME_SINGLE as libc::c_int - } - } - _ => mime_type = MAILMIME_MULTIPLE as libc::c_int, - } - current_block = 12349973810996921269; - } - _ => { - current_block = 13576996419214490990; - } - }, - _ => { - current_block = 13576996419214490990; - } - } - match current_block { - 12349973810996921269 => { - if mime_type == MAILMIME_MULTIPLE as libc::c_int { - let mut attr_name: *mut libc::c_char = 0 as *mut libc::c_char; - let mut attr_value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut param: *mut mailmime_parameter = 0 as *mut mailmime_parameter; - let mut parameters: *mut clist = 0 as *mut clist; - let mut boundary: *mut libc::c_char = 0 as *mut libc::c_char; - list = clist_new(); - if list.is_null() { - current_block = 13576996419214490990; - } else { - attr_name = strdup(b"boundary\x00" as *const u8 as *const libc::c_char); - if attr_name.is_null() { - current_block = 13142422523813476356; - } else { - boundary = mailmime_generate_boundary(); - attr_value = boundary; - if attr_name.is_null() { - free(attr_name as *mut libc::c_void); - current_block = 13142422523813476356; - } else { - param = mailmime_parameter_new(attr_name, attr_value); - if param.is_null() { - free(attr_value as *mut libc::c_void); - free(attr_name as *mut libc::c_void); - current_block = 13142422523813476356; - } else { - if (*content).ct_parameters.is_null() { - parameters = clist_new(); - if parameters.is_null() { - mailmime_parameter_free(param); - current_block = 13142422523813476356; - } else { - current_block = 1836292691772056875; - } - } else { - parameters = (*content).ct_parameters; - current_block = 1836292691772056875; - } - match current_block { - 13142422523813476356 => {} - _ => { - r = clist_insert_after( - parameters, - (*parameters).last, - param as *mut libc::c_void, - ); - if r != 0i32 { - clist_free(parameters); - mailmime_parameter_free(param); - current_block = 13142422523813476356; - } else { - if (*content).ct_parameters.is_null() { - (*content).ct_parameters = parameters - } - current_block = 2543120759711851213; - } - } - } - } - } - } - match current_block { - 2543120759711851213 => {} - _ => { - clist_free(list); - current_block = 13576996419214490990; - } - } - } - } else { - current_block = 2543120759711851213; - } - match current_block { - 13576996419214490990 => {} - _ => { - build_info = mailmime_new( - mime_type, - 0 as *const libc::c_char, - 0i32 as size_t, - mime_fields, - content, - 0 as *mut mailmime_data, - 0 as *mut mailmime_data, - 0 as *mut mailmime_data, - list, - 0 as *mut mailimf_fields, - 0 as *mut Mailmime, - ); - if build_info.is_null() { - clist_free(list); - return 0 as *mut Mailmime; - } - return build_info; - } - } - } - _ => {} - } - return 0 as *mut Mailmime; -} - -pub unsafe fn mailmime_generate_boundary() -> *mut libc::c_char { - let mut rng = thread_rng(); - let value: libc::c_int = rng.gen(); - let now = chrono::Utc::now().timestamp(); - let raw = format!( - "{}_{}_{}", - hex::encode(&now.to_be_bytes()[4..]), - hex::encode(value.to_be_bytes()), - hex::encode(&std::process::id().to_le_bytes()[..2]) - ); - - let c = std::ffi::CString::new(raw).unwrap_or_default(); - strdup(c.as_ptr()) -} - -pub unsafe fn mailmime_new_with_content( - mut content_type: *const libc::c_char, - mut mime_fields: *mut mailmime_fields, - mut result: *mut *mut Mailmime, -) -> libc::c_int { - let mut r: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut content: *mut mailmime_content = 0 as *mut mailmime_content; - let mut build_info: *mut Mailmime = 0 as *mut Mailmime; - let mut res: libc::c_int = 0; - cur_token = 0i32 as size_t; - r = mailmime_content_parse( - content_type, - strlen(content_type), - &mut cur_token, - &mut content, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - build_info = mailmime_new_empty(content, mime_fields); - if build_info.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - mailmime_content_free(content); - } else { - *result = build_info; - return MAILIMF_NO_ERROR as libc::c_int; - } - } - return res; -} - -pub unsafe fn mailmime_set_preamble_file( - mut build_info: *mut Mailmime, - mut filename: *mut libc::c_char, -) -> libc::c_int { - let mut data: *mut mailmime_data = 0 as *mut mailmime_data; - data = mailmime_data_new( - MAILMIME_DATA_FILE as libc::c_int, - MAILMIME_MECHANISM_8BIT as libc::c_int, - 0i32, - 0 as *const libc::c_char, - 0i32 as size_t, - filename, - ); - if data.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - (*build_info).mm_data.mm_multipart.mm_preamble = data; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_set_epilogue_file( - mut build_info: *mut Mailmime, - mut filename: *mut libc::c_char, -) -> libc::c_int { - let mut data: *mut mailmime_data = 0 as *mut mailmime_data; - data = mailmime_data_new( - MAILMIME_DATA_FILE as libc::c_int, - MAILMIME_MECHANISM_8BIT as libc::c_int, - 0i32, - 0 as *const libc::c_char, - 0i32 as size_t, - filename, - ); - if data.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - (*build_info).mm_data.mm_multipart.mm_epilogue = data; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_set_preamble_text( - mut build_info: *mut Mailmime, - mut data_str: *mut libc::c_char, - mut length: size_t, -) -> libc::c_int { - let mut data: *mut mailmime_data = 0 as *mut mailmime_data; - data = mailmime_data_new( - MAILMIME_DATA_TEXT as libc::c_int, - MAILMIME_MECHANISM_8BIT as libc::c_int, - 0i32, - data_str, - length, - 0 as *mut libc::c_char, - ); - if data.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - (*build_info).mm_data.mm_multipart.mm_preamble = data; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_set_epilogue_text( - mut build_info: *mut Mailmime, - mut data_str: *mut libc::c_char, - mut length: size_t, -) -> libc::c_int { - let mut data: *mut mailmime_data = 0 as *mut mailmime_data; - data = mailmime_data_new( - MAILMIME_DATA_TEXT as libc::c_int, - MAILMIME_MECHANISM_8BIT as libc::c_int, - 0i32, - data_str, - length, - 0 as *mut libc::c_char, - ); - if data.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - (*build_info).mm_data.mm_multipart.mm_epilogue = data; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_set_body_file( - mut build_info: *mut Mailmime, - mut filename: *mut libc::c_char, -) -> libc::c_int { - let mut encoding: libc::c_int = 0; - let mut data: *mut mailmime_data = 0 as *mut mailmime_data; - encoding = mailmime_transfer_encoding_get((*build_info).mm_mime_fields); - data = mailmime_data_new( - MAILMIME_DATA_FILE as libc::c_int, - encoding, - 0i32, - 0 as *const libc::c_char, - 0i32 as size_t, - filename, - ); - if data.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - (*build_info).mm_data.mm_single = data; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_set_body_text( - mut build_info: *mut Mailmime, - mut data_str: *mut libc::c_char, - mut length: size_t, -) -> libc::c_int { - let mut encoding: libc::c_int = 0; - let mut data: *mut mailmime_data = 0 as *mut mailmime_data; - encoding = mailmime_transfer_encoding_get((*build_info).mm_mime_fields); - data = mailmime_data_new( - MAILMIME_DATA_TEXT as libc::c_int, - encoding, - 0i32, - data_str, - length, - 0 as *mut libc::c_char, - ); - if data.is_null() { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - (*build_info).mm_data.mm_single = data; - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_add_part( - mut build_info: *mut Mailmime, - mut part: *mut Mailmime, -) -> libc::c_int { - let mut r: libc::c_int = 0; - if (*build_info).mm_type == MAILMIME_MESSAGE as libc::c_int { - (*build_info).mm_data.mm_message.mm_msg_mime = part; - (*part).mm_parent_type = MAILMIME_MESSAGE as libc::c_int; - (*part).mm_parent = build_info - } else if (*build_info).mm_type == MAILMIME_MULTIPLE as libc::c_int { - r = clist_insert_after( - (*build_info).mm_data.mm_multipart.mm_mp_list, - (*(*build_info).mm_data.mm_multipart.mm_mp_list).last, - part as *mut libc::c_void, - ); - if r != 0i32 { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - (*part).mm_parent_type = MAILMIME_MULTIPLE as libc::c_int; - (*part).mm_parent = build_info; - (*part).mm_multipart_pos = (*(*build_info).mm_data.mm_multipart.mm_mp_list).last - } else { - return MAILIMF_ERROR_INVAL as libc::c_int; - } - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_remove_part(mut mime: *mut Mailmime) { - let mut parent: *mut Mailmime = 0 as *mut Mailmime; - parent = (*mime).mm_parent; - if parent.is_null() { - return; - } - match (*mime).mm_parent_type { - 3 => { - (*mime).mm_parent = 0 as *mut Mailmime; - (*parent).mm_data.mm_message.mm_msg_mime = 0 as *mut Mailmime - } - 2 => { - (*mime).mm_parent = 0 as *mut Mailmime; - clist_delete( - (*parent).mm_data.mm_multipart.mm_mp_list, - (*mime).mm_multipart_pos, - ); - } - _ => {} - }; -} - -pub unsafe fn mailmime_set_imf_fields( - mut build_info: *mut Mailmime, - mut mm_fields: *mut mailimf_fields, -) { - (*build_info).mm_data.mm_message.mm_fields = mm_fields; -} - -pub unsafe fn mailmime_single_fields_init( - mut single_fields: *mut mailmime_single_fields, - mut fld_fields: *mut mailmime_fields, - mut fld_content: *mut mailmime_content, -) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - memset( - single_fields as *mut libc::c_void, - 0i32, - ::std::mem::size_of::() as libc::size_t, - ); - if !fld_content.is_null() { - mailmime_content_single_fields_init(single_fields, fld_content); - } - if fld_fields.is_null() { - return; - } - cur = (*(*fld_fields).fld_list).first; - while !cur.is_null() { - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - field = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailmime_field; - match (*field).fld_type { - 1 => { - mailmime_content_single_fields_init(single_fields, (*field).fld_data.fld_content); - } - 2 => (*single_fields).fld_encoding = (*field).fld_data.fld_encoding, - 3 => (*single_fields).fld_id = (*field).fld_data.fld_id, - 4 => (*single_fields).fld_description = (*field).fld_data.fld_description, - 5 => (*single_fields).fld_version = (*field).fld_data.fld_version, - 6 => { - mailmime_disposition_single_fields_init( - single_fields, - (*field).fld_data.fld_disposition, - ); - } - 7 => (*single_fields).fld_language = (*field).fld_data.fld_language, - 8 => (*single_fields).fld_location = (*field).fld_data.fld_location, - _ => {} - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } -} -unsafe fn mailmime_disposition_single_fields_init( - mut single_fields: *mut mailmime_single_fields, - mut fld_disposition: *mut mailmime_disposition, -) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - (*single_fields).fld_disposition = fld_disposition; - cur = (*(*fld_disposition).dsp_parms).first; - while !cur.is_null() { - let mut param: *mut mailmime_disposition_parm = 0 as *mut mailmime_disposition_parm; - param = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailmime_disposition_parm; - match (*param).pa_type { - 0 => (*single_fields).fld_disposition_filename = (*param).pa_data.pa_filename, - 1 => (*single_fields).fld_disposition_creation_date = (*param).pa_data.pa_creation_date, - 2 => { - (*single_fields).fld_disposition_modification_date = - (*param).pa_data.pa_modification_date - } - 3 => (*single_fields).fld_disposition_read_date = (*param).pa_data.pa_read_date, - 4 => (*single_fields).fld_disposition_size = (*param).pa_data.pa_size, - _ => {} - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } -} -unsafe fn mailmime_content_single_fields_init( - mut single_fields: *mut mailmime_single_fields, - mut fld_content: *mut mailmime_content, -) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - (*single_fields).fld_content = fld_content; - cur = (*(*fld_content).ct_parameters).first; - while !cur.is_null() { - let mut param: *mut mailmime_parameter = 0 as *mut mailmime_parameter; - param = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut mailmime_parameter; - if strcasecmp( - (*param).pa_name, - b"boundary\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - (*single_fields).fld_content_boundary = (*param).pa_value - } - if strcasecmp( - (*param).pa_name, - b"charset\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - (*single_fields).fld_content_charset = (*param).pa_value - } - if strcasecmp( - (*param).pa_name, - b"name\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - (*single_fields).fld_content_name = (*param).pa_value - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } -} - -pub unsafe fn mailmime_single_fields_new( - mut fld_fields: *mut mailmime_fields, - mut fld_content: *mut mailmime_content, -) -> *mut mailmime_single_fields { - let mut single_fields: *mut mailmime_single_fields = 0 as *mut mailmime_single_fields; - single_fields = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailmime_single_fields; - if single_fields.is_null() { - return 0 as *mut mailmime_single_fields; - } else { - mailmime_single_fields_init(single_fields, fld_fields, fld_content); - return single_fields; - }; -} - -pub unsafe fn mailmime_single_fields_free(mut single_fields: *mut mailmime_single_fields) { - free(single_fields as *mut libc::c_void); -} - -pub unsafe fn mailmime_smart_add_part( - mut mime: *mut Mailmime, - mut mime_sub: *mut Mailmime, -) -> libc::c_int { - let mut saved_sub: *mut Mailmime = 0 as *mut Mailmime; - let mut mp: *mut Mailmime = 0 as *mut Mailmime; - let mut res: libc::c_int = 0; - let mut r: libc::c_int = 0; - match (*mime).mm_type { - 1 => res = MAILIMF_ERROR_INVAL as libc::c_int, - 2 => { - r = mailmime_add_part(mime, mime_sub); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - return MAILIMF_NO_ERROR as libc::c_int; - } - } - _ => { - /* MAILMIME_MESSAGE */ - if (*mime).mm_data.mm_message.mm_msg_mime.is_null() { - r = mailmime_add_part(mime, mime_sub); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - return MAILIMF_NO_ERROR as libc::c_int; - } - } else { - if (*(*mime).mm_data.mm_message.mm_msg_mime).mm_type - == MAILMIME_MULTIPLE as libc::c_int - { - return mailmime_add_part((*mime).mm_data.mm_message.mm_msg_mime, mime_sub); - } - saved_sub = (*mime).mm_data.mm_message.mm_msg_mime; - mp = mailmime_multiple_new( - b"multipart/mixed\x00" as *const u8 as *const libc::c_char, - ); - if mp.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - mailmime_remove_part(saved_sub); - r = mailmime_add_part(mime, mp); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - mailmime_free(mp); - } else { - r = mailmime_add_part(mp, saved_sub); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - r = mailmime_add_part(mp, mime_sub); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - mailmime_free(saved_sub); - } - } - } - } - return res; -} - -pub unsafe fn mailmime_multiple_new(mut type_0: *const libc::c_char) -> *mut Mailmime { - let mut mime_fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - let mut content: *mut mailmime_content = 0 as *mut mailmime_content; - let mut mp: *mut Mailmime = 0 as *mut Mailmime; - mime_fields = mailmime_fields_new_empty(); - if !mime_fields.is_null() { - content = mailmime_content_new_with_str(type_0); - if !content.is_null() { - mp = mailmime_new_empty(content, mime_fields); - if mp.is_null() { - mailmime_content_free(content); - } else { - return mp; - } - } - mailmime_fields_free(mime_fields); - } - return 0 as *mut Mailmime; -} - -pub unsafe fn mailmime_content_new_with_str(mut str: *const libc::c_char) -> *mut mailmime_content { - let mut r: libc::c_int = 0; - let mut cur_token: size_t = 0; - let mut content: *mut mailmime_content = 0 as *mut mailmime_content; - cur_token = 0i32 as size_t; - r = mailmime_content_parse(str, strlen(str), &mut cur_token, &mut content); - if r != MAILIMF_NO_ERROR as libc::c_int { - return 0 as *mut mailmime_content; - } - return content; -} - -pub unsafe fn mailmime_smart_remove_part(mut mime: *mut Mailmime) -> libc::c_int { - let mut parent: *mut Mailmime = 0 as *mut Mailmime; - let mut res: libc::c_int = 0; - parent = (*mime).mm_parent; - if parent.is_null() { - res = MAILIMF_ERROR_INVAL as libc::c_int - } else { - match (*mime).mm_type { - 3 => { - if !(*mime).mm_data.mm_message.mm_msg_mime.is_null() { - res = MAILIMF_ERROR_INVAL as libc::c_int - } else { - mailmime_remove_part(mime); - mailmime_free(mime); - return MAILIMF_NO_ERROR as libc::c_int; - } - } - 2 => { - if !((*(*mime).mm_data.mm_multipart.mm_mp_list).first - == (*(*mime).mm_data.mm_multipart.mm_mp_list).last - && (*(*mime).mm_data.mm_multipart.mm_mp_list).last.is_null()) - { - res = MAILIMF_ERROR_INVAL as libc::c_int - } else { - mailmime_remove_part(mime); - mailmime_free(mime); - return MAILIMF_NO_ERROR as libc::c_int; - } - } - 1 => { - mailmime_remove_part(mime); - mailmime_free(mime); - return MAILIMF_NO_ERROR as libc::c_int; - } - _ => return MAILIMF_ERROR_INVAL as libc::c_int, - } - } - return res; -} - -pub unsafe fn mailmime_fields_new_encoding(mut type_0: libc::c_int) -> *mut mailmime_fields { - let mut encoding: *mut mailmime_mechanism = 0 as *mut mailmime_mechanism; - let mut mime_fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - encoding = mailmime_mechanism_new(type_0, 0 as *mut libc::c_char); - if !encoding.is_null() { - mime_fields = mailmime_fields_new_with_data( - encoding, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0 as *mut mailmime_disposition, - 0 as *mut mailmime_language, - ); - if mime_fields.is_null() { - mailmime_mechanism_free(encoding); - } else { - return mime_fields; - } - } - return 0 as *mut mailmime_fields; -} - -pub unsafe fn mailmime_fields_new_filename( - mut dsp_type: libc::c_int, - mut filename: *mut libc::c_char, - mut encoding_type: libc::c_int, -) -> *mut mailmime_fields { - let mut dsp: *mut mailmime_disposition = 0 as *mut mailmime_disposition; - let mut encoding: *mut mailmime_mechanism = 0 as *mut mailmime_mechanism; - let mut mime_fields: *mut mailmime_fields = 0 as *mut mailmime_fields; - dsp = mailmime_disposition_new_with_data( - dsp_type, - filename, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - -1i32 as size_t, - ); - if !dsp.is_null() { - encoding = mailmime_mechanism_new(encoding_type, 0 as *mut libc::c_char); - if !encoding.is_null() { - mime_fields = mailmime_fields_new_with_data( - encoding, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - dsp, - 0 as *mut mailmime_language, - ); - if mime_fields.is_null() { - mailmime_encoding_free(encoding); - } else { - return mime_fields; - } - } - mailmime_disposition_free(dsp); - } - return 0 as *mut mailmime_fields; -} - -pub unsafe fn mailmime_param_new_with_data( - mut name: *mut libc::c_char, - mut value: *mut libc::c_char, -) -> *mut mailmime_parameter { - let mut param_name: *mut libc::c_char = 0 as *mut libc::c_char; - let mut param_value: *mut libc::c_char = 0 as *mut libc::c_char; - let mut param: *mut mailmime_parameter = 0 as *mut mailmime_parameter; - param_name = strdup(name); - if !param_name.is_null() { - param_value = strdup(value); - if !param_value.is_null() { - param = mailmime_parameter_new(param_name, param_value); - if param.is_null() { - free(param_value as *mut libc::c_void); - } else { - return param; - } - } - free(param_name as *mut libc::c_void); - } - return 0 as *mut mailmime_parameter; -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_generate_boundary() { - let res_c = unsafe { mailmime_generate_boundary() }; - let res = unsafe { std::ffi::CStr::from_ptr(res_c).to_str().unwrap() }; - assert_eq!(res.len(), 22); - - unsafe { free(res_c as *mut _) }; - } -} diff --git a/mmime/src/mailmime/write_generic.rs b/mmime/src/mailmime/write_generic.rs deleted file mode 100644 index cc951e5f2..000000000 --- a/mmime/src/mailmime/write_generic.rs +++ /dev/null @@ -1,1979 +0,0 @@ -use std::ffi::CStr; - -use crate::clist::*; -use crate::mailimf::write_generic::*; -use crate::mailmime::content::*; -use crate::mailmime::types::*; -use crate::mailmime::types_helper::*; -use crate::mailmime::*; -use crate::other::*; - -pub const STATE_INIT: libc::c_uint = 0; -pub const STATE_SPACE_CR: libc::c_uint = 3; -pub const STATE_SPACE: libc::c_uint = 2; -pub const STATE_CR: libc::c_uint = 1; - -pub unsafe fn mailmime_fields_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut fields: *mut mailmime_fields, -) -> libc::c_int { - let mut r: libc::c_int = 0; - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*fields).fld_list).first; - while !cur.is_null() { - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - field = (*cur).data as *mut mailmime_field; - r = mailmime_field_write_driver(do_write, data, col, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - return MAILIMF_NO_ERROR as libc::c_int; -} - -unsafe fn mailmime_field_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut field: *mut mailmime_field, -) -> libc::c_int { - let mut r: libc::c_int = 0; - match (*field).fld_type { - 1 => r = mailmime_content_write_driver(do_write, data, col, (*field).fld_data.fld_content), - 2 => { - r = mailmime_encoding_write_driver(do_write, data, col, (*field).fld_data.fld_encoding) - } - 3 => r = mailmime_id_write_driver(do_write, data, col, (*field).fld_data.fld_id), - 4 => { - r = mailmime_description_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_description, - ) - } - 5 => r = mailmime_version_write_driver(do_write, data, col, (*field).fld_data.fld_version), - 6 => { - r = mailmime_disposition_write_driver( - do_write, - data, - col, - (*field).fld_data.fld_disposition, - ) - } - 7 => { - r = mailmime_language_write_driver(do_write, data, col, (*field).fld_data.fld_language) - } - 8 => { - r = mailmime_location_write_driver(do_write, data, col, (*field).fld_data.fld_location) - } - _ => r = MAILIMF_ERROR_INVAL as libc::c_int, - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_location_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut location: *mut libc::c_char, -) -> libc::c_int { - let mut r: libc::c_int = 0; - let mut len: libc::c_int = strlen(location) as libc::c_int; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Content-Location: \x00" as *const u8 as *const libc::c_char, - 18i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - if *col > 1i32 && *col + len > 78i32 { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - r = mailimf_string_write_driver(do_write, data, col, location, len as size_t); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_language_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut language: *mut mailmime_language, -) -> libc::c_int { - let mut r: libc::c_int = 0; - let mut cur: *mut clistiter = 0 as *mut clistiter; - let mut first: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Content-Language: \x00" as *const u8 as *const libc::c_char, - 18i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - first = 1i32; - cur = (*(*language).lg_list).first; - while !cur.is_null() { - let mut lang: *mut libc::c_char = 0 as *mut libc::c_char; - let mut len: size_t = 0; - lang = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut libc::c_char; - len = strlen(lang); - if 0 == first { - r = mailimf_string_write_driver( - do_write, - data, - col, - b", \x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } else { - first = 0i32 - } - if *col > 1i32 { - if (*col as libc::size_t).wrapping_add(len) > 78i32 as libc::size_t { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - } - r = mailimf_string_write_driver(do_write, data, col, lang, len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_disposition_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut disposition: *mut mailmime_disposition, -) -> libc::c_int { - let mut dsp_type: *mut mailmime_disposition_type = 0 as *mut mailmime_disposition_type; - let mut r: libc::c_int = 0; - let mut cur: *mut clistiter = 0 as *mut clistiter; - dsp_type = (*disposition).dsp_type; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Content-Disposition: \x00" as *const u8 as *const libc::c_char, - 21i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - match (*dsp_type).dsp_type { - 1 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"inline\x00" as *const u8 as *const libc::c_char, - 6i32 as size_t, - ) - } - 2 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"attachment\x00" as *const u8 as *const libc::c_char, - 10i32 as size_t, - ) - } - 3 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - (*dsp_type).dsp_extension, - strlen((*dsp_type).dsp_extension), - ) - } - _ => r = MAILIMF_ERROR_INVAL as libc::c_int, - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - cur = (*(*disposition).dsp_parms).first; - while !cur.is_null() { - let mut param: *mut mailmime_disposition_parm = 0 as *mut mailmime_disposition_parm; - param = (*cur).data as *mut mailmime_disposition_parm; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"; \x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailmime_disposition_param_write_driver(do_write, data, col, param); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_disposition_param_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut param: *mut mailmime_disposition_parm, -) -> libc::c_int { - let mut len: size_t = 0; - let mut r: libc::c_int = 0; - let mut sizestr: *mut libc::c_char = std::ptr::null_mut(); - - match (*param).pa_type { - 0 => { - len = strlen(b"filename=\x00" as *const u8 as *const libc::c_char) - .wrapping_add(strlen((*param).pa_data.pa_filename)) - } - 1 => { - len = strlen(b"creation-date=\x00" as *const u8 as *const libc::c_char) - .wrapping_add(strlen((*param).pa_data.pa_creation_date)) - } - 2 => { - len = strlen(b"modification-date=\x00" as *const u8 as *const libc::c_char) - .wrapping_add(strlen((*param).pa_data.pa_modification_date)) - } - 3 => { - len = strlen(b"read-date=\x00" as *const u8 as *const libc::c_char) - .wrapping_add(strlen((*param).pa_data.pa_read_date)) - } - 4 => { - let value = (*param).pa_data.pa_size as u32; - let raw = format!("{}", value); - let raw_c = std::ffi::CString::new(raw).unwrap_or_default(); - sizestr = strdup(raw_c.as_ptr()); - len = strlen(b"size=\x00" as *const u8 as *const libc::c_char) - .wrapping_add(strlen(sizestr)) - } - 5 => { - len = strlen((*(*param).pa_data.pa_parameter).pa_name) - .wrapping_add(1i32 as libc::size_t) - .wrapping_add(strlen((*(*param).pa_data.pa_parameter).pa_value)) - } - _ => return MAILIMF_ERROR_INVAL as libc::c_int, - } - if *col > 1i32 { - if (*col as libc::size_t).wrapping_add(len) > 78i32 as libc::size_t { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - } - match (*param).pa_type { - 0 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"filename=\x00" as *const u8 as *const libc::c_char, - 9i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_quoted_string_write_driver( - do_write, - data, - col, - (*param).pa_data.pa_filename, - strlen((*param).pa_data.pa_filename), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 1 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"creation-date=\x00" as *const u8 as *const libc::c_char, - 14i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_quoted_string_write_driver( - do_write, - data, - col, - (*param).pa_data.pa_creation_date, - strlen((*param).pa_data.pa_creation_date), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 2 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"modification-date=\x00" as *const u8 as *const libc::c_char, - 18i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_quoted_string_write_driver( - do_write, - data, - col, - (*param).pa_data.pa_modification_date, - strlen((*param).pa_data.pa_modification_date), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 3 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"read-date=\x00" as *const u8 as *const libc::c_char, - 10i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_quoted_string_write_driver( - do_write, - data, - col, - (*param).pa_data.pa_read_date, - strlen((*param).pa_data.pa_read_date), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 4 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"size=\x00" as *const u8 as *const libc::c_char, - 5i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver(do_write, data, col, sizestr, strlen(sizestr)); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - 5 => { - r = mailmime_parameter_write_driver(do_write, data, col, (*param).pa_data.pa_parameter); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - _ => {} - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_parameter_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut param: *mut mailmime_parameter, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - (*param).pa_name, - strlen((*param).pa_name), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"=\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_quoted_string_write_driver( - do_write, - data, - col, - (*param).pa_value, - strlen((*param).pa_value), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_version_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut version: uint32_t, -) -> libc::c_int { - let mut r: libc::c_int = 0; - - r = mailimf_string_write_driver( - do_write, - data, - col, - b"MIME-Version: \x00" as *const u8 as *const libc::c_char, - 14i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - - let raw = format!("{}.{}", (version >> 16) as i32, (version & 0xffff) as i32); - let raw_c = std::ffi::CString::new(raw).unwrap_or_default(); - let mut versionstr = strdup(raw_c.as_ptr()); - r = mailimf_string_write_driver(do_write, data, col, versionstr, strlen(versionstr)); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_description_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut descr: *mut libc::c_char, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Content-Description: \x00" as *const u8 as *const libc::c_char, - 21i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver(do_write, data, col, descr, strlen(descr)); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_id_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut id: *mut libc::c_char, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Content-ID: \x00" as *const u8 as *const libc::c_char, - 12i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"<\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver(do_write, data, col, id, strlen(id)); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b">\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_encoding_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut encoding: *mut mailmime_mechanism, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Content-Transfer-Encoding: \x00" as *const u8 as *const libc::c_char, - 27i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - match (*encoding).enc_type { - 1 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"7bit\x00" as *const u8 as *const libc::c_char, - 4i32 as size_t, - ) - } - 2 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"8bit\x00" as *const u8 as *const libc::c_char, - 4i32 as size_t, - ) - } - 3 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"binary\x00" as *const u8 as *const libc::c_char, - 6i32 as size_t, - ) - } - 4 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"quoted-printable\x00" as *const u8 as *const libc::c_char, - 16i32 as size_t, - ) - } - 5 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"base64\x00" as *const u8 as *const libc::c_char, - 6i32 as size_t, - ) - } - 6 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - (*encoding).enc_token, - strlen((*encoding).enc_token), - ) - } - _ => r = MAILIMF_ERROR_INVAL as libc::c_int, - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_content_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut content: *mut mailmime_content, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"Content-Type: \x00" as *const u8 as *const libc::c_char, - 14i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailmime_content_type_write_driver(do_write, data, col, content); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_content_type_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut content: *mut mailmime_content, -) -> libc::c_int { - let mut cur: *mut clistiter = 0 as *mut clistiter; - let mut len: size_t = 0; - let mut r: libc::c_int = 0; - r = mailmime_type_write_driver(do_write, data, col, (*content).ct_type); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"/\x00" as *const u8 as *const libc::c_char, - 1i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - r = mailimf_string_write_driver( - do_write, - data, - col, - (*content).ct_subtype, - strlen((*content).ct_subtype), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - if !(*content).ct_parameters.is_null() { - cur = (*(*content).ct_parameters).first; - while !cur.is_null() { - let mut param: *mut mailmime_parameter = 0 as *mut mailmime_parameter; - param = (*cur).data as *mut mailmime_parameter; - r = mailimf_string_write_driver( - do_write, - data, - col, - b"; \x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - len = strlen((*param).pa_name) - .wrapping_add(1i32 as libc::size_t) - .wrapping_add(strlen((*param).pa_value)); - if *col > 1i32 { - if (*col as libc::size_t).wrapping_add(len) > 78i32 as libc::size_t { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n \x00" as *const u8 as *const libc::c_char, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - } - r = mailmime_parameter_write_driver(do_write, data, col, param); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - } - return MAILIMF_NO_ERROR as libc::c_int; -} -/* -static int mailmime_content_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col, - struct mailmime_content * content); -*/ -unsafe fn mailmime_type_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut type_0: *mut mailmime_type, -) -> libc::c_int { - let mut r: libc::c_int = 0; - match (*type_0).tp_type { - 1 => { - r = mailmime_discrete_type_write_driver( - do_write, - data, - col, - (*type_0).tp_data.tp_discrete_type, - ) - } - 2 => { - r = mailmime_composite_type_write_driver( - do_write, - data, - col, - (*type_0).tp_data.tp_composite_type, - ) - } - _ => r = MAILIMF_ERROR_INVAL as libc::c_int, - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_composite_type_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut composite_type: *mut mailmime_composite_type, -) -> libc::c_int { - let mut r: libc::c_int = 0; - match (*composite_type).ct_type { - 1 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"message\x00" as *const u8 as *const libc::c_char, - 7i32 as size_t, - ) - } - 2 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"multipart\x00" as *const u8 as *const libc::c_char, - 9i32 as size_t, - ) - } - 3 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - (*composite_type).ct_token, - strlen((*composite_type).ct_token), - ) - } - _ => r = MAILIMF_ERROR_INVAL as libc::c_int, - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -unsafe fn mailmime_discrete_type_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut discrete_type: *mut mailmime_discrete_type, -) -> libc::c_int { - let mut r: libc::c_int = 0; - match (*discrete_type).dt_type { - 1 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"text\x00" as *const u8 as *const libc::c_char, - 4i32 as size_t, - ) - } - 2 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"image\x00" as *const u8 as *const libc::c_char, - 5i32 as size_t, - ) - } - 3 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"audio\x00" as *const u8 as *const libc::c_char, - 5i32 as size_t, - ) - } - 4 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"video\x00" as *const u8 as *const libc::c_char, - 5i32 as size_t, - ) - } - 5 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"application\x00" as *const u8 as *const libc::c_char, - 11i32 as size_t, - ) - } - 6 => { - r = mailimf_string_write_driver( - do_write, - data, - col, - (*discrete_type).dt_extension, - strlen((*discrete_type).dt_extension), - ) - } - _ => r = MAILIMF_ERROR_INVAL as libc::c_int, - } - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} - -pub unsafe fn mailmime_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut build_info: *mut Mailmime, -) -> libc::c_int { - if !(*build_info).mm_parent.is_null() { - return mailmime_sub_write_driver(do_write, data, col, build_info); - } else { - return mailmime_part_write_driver(do_write, data, col, build_info); - }; -} -/* -static int mailmime_base64_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col, - char * text, size_t size); - -static int mailmime_quoted_printable_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col, int istext, - char * text, size_t size); -*/ -unsafe fn mailmime_part_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut build_info: *mut Mailmime, -) -> libc::c_int { - let mut current_block: u64; - let mut cur: *mut clistiter = 0 as *mut clistiter; - let mut first: libc::c_int = 0; - let mut r: libc::c_int = 0; - let mut boundary: *mut libc::c_char = 0 as *mut libc::c_char; - let mut istext: libc::c_int = 0; - let mut res: libc::c_int = 0; - istext = 1i32; - boundary = 0 as *mut libc::c_char; - if !(*build_info).mm_content_type.is_null() { - if (*build_info).mm_type == MAILMIME_MULTIPLE as libc::c_int { - boundary = mailmime_extract_boundary((*build_info).mm_content_type); - if boundary.is_null() { - boundary = mailmime_generate_boundary(); - if boundary.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 13530634675565645571; - } else { - current_block = 13586036798005543211; - } - } else { - current_block = 13586036798005543211; - } - } else { - current_block = 13586036798005543211; - } - match current_block { - 13530634675565645571 => {} - _ => { - if (*(*(*build_info).mm_content_type).ct_type).tp_type - == MAILMIME_TYPE_DISCRETE_TYPE as libc::c_int - { - if (*(*(*(*build_info).mm_content_type).ct_type) - .tp_data - .tp_discrete_type) - .dt_type - != MAILMIME_DISCRETE_TYPE_TEXT as libc::c_int - { - istext = 0i32 - } - } - current_block = 8457315219000651999; - } - } - } else { - current_block = 8457315219000651999; - } - match current_block { - 8457315219000651999 => { - match (*build_info).mm_type { - 1 => { - /* 1-part body */ - if !(*build_info).mm_data.mm_single.is_null() { - r = mailmime_data_write_driver( - do_write, - data, - col, - (*build_info).mm_data.mm_single, - istext, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else { - current_block = 7639320476250304355; - } - } else { - current_block = 7639320476250304355; - } - } - 2 => { - /* multi-part */ - /* preamble */ - if !(*build_info).mm_data.mm_multipart.mm_preamble.is_null() { - r = mailmime_data_write_driver( - do_write, - data, - col, - (*build_info).mm_data.mm_multipart.mm_preamble, - 1i32, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else { - current_block = 17500079516916021833; - } - } - } else { - current_block = 17500079516916021833; - } - match current_block { - 16754986508692159943 => {} - _ => { - first = 1i32; - cur = (*(*build_info).mm_data.mm_multipart.mm_mp_list).first; - loop { - if cur.is_null() { - current_block = 3546145585875536353; - break; - } - let mut subpart: *mut Mailmime = 0 as *mut Mailmime; - subpart = (*cur).data as *mut Mailmime; - if 0 == first { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - break; - } - } else { - first = 0i32 - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"--\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - break; - } else if boundary.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 16754986508692159943; - break; - } else { - r = mailimf_string_write_driver( - do_write, - data, - col, - boundary, - strlen(boundary), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - break; - } else { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - break; - } else { - r = mailmime_sub_write_driver( - do_write, data, col, subpart, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - break; - } else { - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - } - } - } - } - match current_block { - 16754986508692159943 => {} - _ => { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"--\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else if boundary.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int; - current_block = 16754986508692159943; - } else { - r = mailimf_string_write_driver( - do_write, - data, - col, - boundary, - strlen(boundary), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"--\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 - as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else if !(*build_info) - .mm_data - .mm_multipart - .mm_epilogue - .is_null() - { - r = mailmime_data_write_driver( - do_write, - data, - col, - (*build_info) - .mm_data - .mm_multipart - .mm_epilogue, - 1i32, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else { - current_block = 7639320476250304355; - } - } else { - current_block = 7639320476250304355; - } - } - } - } - } - } - } - } - } - } - 3 => { - if !(*build_info).mm_data.mm_message.mm_fields.is_null() { - r = mailimf_fields_write_driver( - do_write, - data, - col, - (*build_info).mm_data.mm_message.mm_fields, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else { - current_block = 2798392256336243897; - } - } else { - current_block = 2798392256336243897; - } - match current_block { - 16754986508692159943 => {} - _ => { - if !(*build_info).mm_mime_fields.is_null() { - let mut r_0: libc::c_int = 0; - let mut cur_0: *mut clistiter = 0 as *mut clistiter; - cur_0 = (*(*(*build_info).mm_mime_fields).fld_list).first; - loop { - if cur_0.is_null() { - current_block = 562309032768341766; - break; - } - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - field = (*cur_0).data as *mut mailmime_field; - if (*field).fld_type == MAILMIME_FIELD_VERSION as libc::c_int { - r_0 = - mailmime_field_write_driver(do_write, data, col, field); - if r_0 != MAILIMF_NO_ERROR as libc::c_int { - res = r_0; - current_block = 16754986508692159943; - break; - } - } - cur_0 = if !cur_0.is_null() { - (*cur_0).next - } else { - 0 as *mut clistcell - } - } - } else { - current_block = 562309032768341766; - } - match current_block { - 16754986508692159943 => {} - _ => { - /* encapsuled message */ - if !(*build_info).mm_data.mm_message.mm_msg_mime.is_null() { - r = mailmime_sub_write_driver( - do_write, - data, - col, - (*build_info).mm_data.mm_message.mm_msg_mime, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 16754986508692159943; - } else { - current_block = 7639320476250304355; - } - } else { - current_block = 7639320476250304355; - } - } - } - } - } - } - _ => { - current_block = 7639320476250304355; - } - } - match current_block { - 16754986508692159943 => { - free(boundary as *mut libc::c_void); - } - _ => { - free(boundary as *mut libc::c_void); - return MAILIMF_NO_ERROR as libc::c_int; - } - } - } - _ => {} - } - return res; -} -unsafe fn mailmime_sub_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut build_info: *mut Mailmime, -) -> libc::c_int { - let mut r: libc::c_int = 0; - if !(*build_info).mm_content_type.is_null() { - r = mailmime_content_write_driver(do_write, data, col, (*build_info).mm_content_type); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - if (*build_info).mm_type != MAILMIME_MESSAGE as libc::c_int { - if !(*build_info).mm_mime_fields.is_null() { - r = mailmime_fields_write_driver(do_write, data, col, (*build_info).mm_mime_fields); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - } else if !(*build_info).mm_mime_fields.is_null() { - let mut r_0: libc::c_int = 0; - let mut cur: *mut clistiter = 0 as *mut clistiter; - cur = (*(*(*build_info).mm_mime_fields).fld_list).first; - while !cur.is_null() { - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - field = (*cur).data as *mut mailmime_field; - if (*field).fld_type != MAILMIME_FIELD_VERSION as libc::c_int { - r_0 = mailmime_field_write_driver(do_write, data, col, field); - if r_0 != MAILIMF_NO_ERROR as libc::c_int { - return r_0; - } - } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return mailmime_part_write_driver(do_write, data, col, build_info); -} - -pub unsafe fn mailmime_data_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut mime_data: *mut mailmime_data, - mut istext: libc::c_int, -) -> libc::c_int { - let mut current_block: u64 = 0; - let mut fd: libc::c_int = 0; - let mut r: libc::c_int = 0; - let mut text: *mut libc::c_char = 0 as *mut libc::c_char; - - let mut res: libc::c_int = 0; - match (*mime_data).dt_type { - 0 => { - if 0 != (*mime_data).dt_encoded { - r = mailimf_string_write_driver( - do_write, - data, - col, - (*mime_data).dt_data.dt_text.dt_data, - (*mime_data).dt_data.dt_text.dt_length, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } else { - r = mailmime_text_content_write_driver( - do_write, - data, - col, - (*mime_data).dt_encoding, - istext, - (*mime_data).dt_data.dt_text.dt_data, - (*mime_data).dt_data.dt_text.dt_length, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - } - 1 => { - let filename = CStr::from_ptr((*mime_data).dt_data.dt_filename) - .to_string_lossy() - .into_owned(); - if let Ok(file) = std::fs::File::open(filename) { - if let Ok(mut text) = memmap::MmapOptions::new().map_copy(&file) { - if 0 != (*mime_data).dt_encoded { - r = mailimf_string_write_driver( - do_write, - data, - col, - text.as_ptr() as *const _, - text.len(), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 1055471768422549395; - } else { - current_block = 1538046216550696469; - } - } else { - r = mailmime_text_content_write_driver( - do_write, - data, - col, - (*mime_data).dt_encoding, - istext, - text.as_ptr() as *const _, - text.len(), - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - res = r; - current_block = 1055471768422549395; - } else { - current_block = 1538046216550696469; - } - } - match current_block { - 1055471768422549395 => { - current_block = 5221028069996397600; - } - _ => { - current_block = 9853141518545631134; - } - } - } else { - res = MAILIMF_ERROR_FILE as libc::c_int; - current_block = 5221028069996397600; - } - match current_block { - 5221028069996397600 => {} - _ => { - close(fd); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - current_block = 10891380440665537214; - } - } - } else { - res = MAILIMF_ERROR_FILE as libc::c_int; - current_block = 10275258781883576179; - } - match current_block { - 10891380440665537214 => {} - _ => { - current_block = 10275258781883576179; - } - } - match current_block { - 10891380440665537214 => {} - _ => return res, - } - } - _ => {} - } - return MAILIMF_NO_ERROR as libc::c_int; -} -/* ****************************************************************** */ -/* message */ -/* -static int mailmime_data_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col, - struct mailmime_data * data, - int is_text); -*/ -unsafe fn mailmime_text_content_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut encoding: libc::c_int, - mut istext: libc::c_int, - mut text: *const libc::c_char, - mut size: size_t, -) -> libc::c_int { - match encoding { - 4 => { - return mailmime_quoted_printable_write_driver(do_write, data, col, istext, text, size) - } - 5 => return mailmime_base64_write_driver(do_write, data, col, text, size), - 1 | 2 | 3 | _ => return mailimf_string_write_driver(do_write, data, col, text, size), - }; -} - -pub unsafe fn mailmime_base64_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut text: *const libc::c_char, - mut size: size_t, -) -> libc::c_int { - let mut a: libc::c_int = 0; - let mut b: libc::c_int = 0; - let mut c: libc::c_int = 0; - let mut remains: size_t = 0; - let mut p: *const libc::c_char = 0 as *const libc::c_char; - let mut count: size_t = 0; - let mut ogroup: [libc::c_char; 4] = [0; 4]; - let mut r: libc::c_int = 0; - remains = size; - p = text; - while remains > 0i32 as libc::size_t { - match remains { - 1 => { - a = *p.offset(0isize) as libc::c_uchar as libc::c_int; - b = 0i32; - c = 0i32; - count = 1i32 as size_t - } - 2 => { - a = *p.offset(0isize) as libc::c_uchar as libc::c_int; - b = *p.offset(1isize) as libc::c_uchar as libc::c_int; - c = 0i32; - count = 2i32 as size_t - } - _ => { - a = *p.offset(0isize) as libc::c_uchar as libc::c_int; - b = *p.offset(1isize) as libc::c_uchar as libc::c_int; - c = *p.offset(2isize) as libc::c_uchar as libc::c_int; - count = 3i32 as size_t - } - } - ogroup[0usize] = base64_encoding[(a >> 2i32) as usize]; - ogroup[1usize] = base64_encoding[((a & 3i32) << 4i32 | b >> 4i32) as usize]; - ogroup[2usize] = base64_encoding[((b & 0xfi32) << 2i32 | c >> 6i32) as usize]; - ogroup[3usize] = base64_encoding[(c & 0x3fi32) as usize]; - match count { - 1 => { - ogroup[2usize] = '=' as i32 as libc::c_char; - ogroup[3usize] = '=' as i32 as libc::c_char - } - 2 => ogroup[3usize] = '=' as i32 as libc::c_char, - _ => {} - } - if *col + 4i32 > 76i32 { - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - r = mailimf_string_write_driver(do_write, data, col, ogroup.as_mut_ptr(), 4i32 as size_t); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - remains = (remains as libc::size_t).wrapping_sub(count) as size_t as size_t; - p = p.offset(count as isize) - } - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - return MAILIMF_NO_ERROR as libc::c_int; -} -static mut base64_encoding: [libc::c_char; 65] = [ - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 0, -]; - -pub unsafe fn mailmime_quoted_printable_write_driver( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut istext: libc::c_int, - mut text: *const libc::c_char, - mut size: size_t, -) -> libc::c_int { - let mut i: size_t = 0; - let mut start: *const libc::c_char = 0 as *const libc::c_char; - let mut len: size_t = 0; - let mut r: libc::c_int = 0; - let mut state: libc::c_int = 0; - start = text; - len = 0i32 as size_t; - state = STATE_INIT as libc::c_int; - i = 0i32 as size_t; - while i < size { - let mut ch: libc::c_uchar = 0; - if (*col as libc::size_t).wrapping_add(len) > 72i32 as libc::size_t { - r = write_remaining(do_write, data, col, &mut start, &mut len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - start = text.offset(i as isize); - r = mailimf_string_write_driver( - do_write, - data, - col, - b"=\r\n\x00" as *const u8 as *const libc::c_char, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - } - ch = *text.offset(i as isize) as libc::c_uchar; - match state { - 0 => { - let mut current_block_50: u64; - match ch as libc::c_int { - 32 | 9 => { - state = STATE_SPACE as libc::c_int; - len = len.wrapping_add(1); - i = i.wrapping_add(1); - current_block_50 = 3546145585875536353; - } - 13 => { - state = STATE_CR as libc::c_int; - i = i.wrapping_add(1); - current_block_50 = 3546145585875536353; - } - 33 | 34 | 35 | 36 | 64 | 91 | 92 | 93 | 94 | 96 | 123 | 124 | 125 | 126 - | 61 | 63 | 95 => { - /* there is no more 'From' at the beginning of a line */ - current_block_50 = 177397332496894159; - } - 70 => { - current_block_50 = 177397332496894159; - } - _ => { - if 0 != istext && ch as libc::c_int == '\n' as i32 { - r = write_remaining(do_write, data, col, &mut start, &mut len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - start = text.offset(i as isize).offset(1isize); - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - i = i.wrapping_add(1) - } else if ch as libc::c_int >= 33i32 && ch as libc::c_int <= 60i32 - || ch as libc::c_int >= 62i32 && ch as libc::c_int <= 126i32 - { - len = len.wrapping_add(1); - i = i.wrapping_add(1) - } else { - r = write_remaining(do_write, data, col, &mut start, &mut len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - start = text.offset(i as isize).offset(1isize); - - let raw = format!("={:02X}", (ch as libc::c_int)); - let raw_c = std::ffi::CString::new(raw).unwrap_or_default(); - let mut hexstr = strdup(raw_c.as_ptr()); - r = mailimf_string_write_driver( - do_write, - data, - col, - hexstr, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - i = i.wrapping_add(1) - } - current_block_50 = 3546145585875536353; - } - } - match current_block_50 { - 177397332496894159 => { - r = write_remaining(do_write, data, col, &mut start, &mut len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - start = text.offset(i as isize).offset(1isize); - let raw = format!("={:02X}", ch as libc::c_int); - let raw_c = std::ffi::CString::new(raw).unwrap_or_default(); - let mut hexstr = strdup(raw_c.as_ptr()); - r = mailimf_string_write_driver( - do_write, - data, - col, - hexstr, - 3i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - i = i.wrapping_add(1) - } - _ => {} - } - } - 1 => match ch as libc::c_int { - 10 => { - r = write_remaining(do_write, data, col, &mut start, &mut len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - start = text.offset(i as isize).offset(1isize); - r = mailimf_string_write_driver( - do_write, - data, - col, - b"\r\n\x00" as *const u8 as *const libc::c_char, - 2i32 as size_t, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - i = i.wrapping_add(1); - state = STATE_INIT as libc::c_int - } - _ => { - r = write_remaining(do_write, data, col, &mut start, &mut len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - start = text.offset(i as isize); - let raw = format!("={:02X}", b'\r' as i32); - let raw_c = std::ffi::CString::new(raw).unwrap_or_default(); - let mut hexstr = strdup(raw_c.as_ptr()); - r = mailimf_string_write_driver(do_write, data, col, hexstr, 3i32 as size_t); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - state = STATE_INIT as libc::c_int - } - }, - 2 => match ch as libc::c_int { - 13 => { - state = STATE_SPACE_CR as libc::c_int; - i = i.wrapping_add(1) - } - 10 => { - r = write_remaining(do_write, data, col, &mut start, &mut len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - start = text.offset(i as isize).offset(1isize); - let raw = format!( - "={:02X}\r\n", - *text.offset(i.wrapping_sub(1i32 as libc::size_t) as isize) as libc::c_int - ); - let raw_c = std::ffi::CString::new(raw).unwrap_or_default(); - let mut hexstr = strdup(raw_c.as_ptr()); - - r = mailimf_string_write_driver(do_write, data, col, hexstr, strlen(hexstr)); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - state = STATE_INIT as libc::c_int; - i = i.wrapping_add(1) - } - 32 | 9 => { - len = len.wrapping_add(1); - i = i.wrapping_add(1) - } - _ => state = STATE_INIT as libc::c_int, - }, - 3 => match ch as libc::c_int { - 10 => { - r = write_remaining(do_write, data, col, &mut start, &mut len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - start = text.offset(i as isize).offset(1isize); - let raw = format!( - "={:02X}\r\n", - *text.offset(i.wrapping_sub(2i32 as libc::size_t) as isize) as libc::c_int - ); - let raw_c = std::ffi::CString::new(raw).unwrap_or_default(); - let mut hexstr = strdup(raw_c.as_ptr()); - - r = mailimf_string_write_driver(do_write, data, col, hexstr, strlen(hexstr)); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - state = STATE_INIT as libc::c_int; - i = i.wrapping_add(1) - } - _ => { - r = write_remaining(do_write, data, col, &mut start, &mut len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - start = text.offset(i as isize).offset(1isize); - let raw = format!( - "{}={:02X}\r\n", - (*text.offset(i.wrapping_sub(2i32 as libc::size_t) as isize) as u8 as char), - b'\r' as i32 - ); - let raw_c = std::ffi::CString::new(raw).unwrap_or_default(); - let mut hexstr = strdup(raw_c.as_ptr()); - - r = mailimf_string_write_driver(do_write, data, col, hexstr, strlen(hexstr)); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - state = STATE_INIT as libc::c_int - } - }, - _ => {} - } - } - r = write_remaining(do_write, data, col, &mut start, &mut len); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - return MAILIMF_NO_ERROR as libc::c_int; -} -#[inline] -unsafe fn write_remaining( - mut do_write: Option< - unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, - >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut pstart: *mut *const libc::c_char, - mut plen: *mut size_t, -) -> libc::c_int { - let mut r: libc::c_int = 0; - if *plen > 0i32 as libc::size_t { - r = mailimf_string_write_driver(do_write, data, col, *pstart, *plen); - if r != MAILIMF_NO_ERROR as libc::c_int { - return r; - } - *plen = 0i32 as size_t - } - return MAILIMF_NO_ERROR as libc::c_int; -} diff --git a/mmime/src/mailmime/write_mem.rs b/mmime/src/mailmime/write_mem.rs deleted file mode 100644 index 1cf0bc58d..000000000 --- a/mmime/src/mailmime/write_mem.rs +++ /dev/null @@ -1,82 +0,0 @@ -use crate::mailmime::types::*; -use crate::mailmime::write_generic::*; -use crate::mmapstring::*; -use crate::other::*; - -unsafe fn do_write( - mut data: *mut libc::c_void, - mut str: *const libc::c_char, - mut length: size_t, -) -> libc::c_int { - let mut f: *mut MMAPString = 0 as *mut MMAPString; - f = data as *mut MMAPString; - if mmap_string_append_len(f, str, length).is_null() { - return 0i32; - } else { - return length as libc::c_int; - }; -} - -pub unsafe fn mailmime_content_write_mem( - mut f: *mut MMAPString, - mut col: *mut libc::c_int, - mut content: *mut mailmime_content, -) -> libc::c_int { - return mailmime_content_write_driver(Some(do_write), f as *mut libc::c_void, col, content); -} - -pub unsafe fn mailmime_content_type_write_mem( - mut f: *mut MMAPString, - mut col: *mut libc::c_int, - mut content: *mut mailmime_content, -) -> libc::c_int { - return mailmime_content_type_write_driver( - Some(do_write), - f as *mut libc::c_void, - col, - content, - ); -} - -pub unsafe fn mailmime_write_mem( - mut f: *mut MMAPString, - mut col: *mut libc::c_int, - mut build_info: *mut Mailmime, -) -> libc::c_int { - return mailmime_write_driver(Some(do_write), f as *mut libc::c_void, col, build_info); -} - -pub unsafe fn mailmime_quoted_printable_write_mem( - mut f: *mut MMAPString, - mut col: *mut libc::c_int, - mut istext: libc::c_int, - mut text: *const libc::c_char, - mut size: size_t, -) -> libc::c_int { - return mailmime_quoted_printable_write_driver( - Some(do_write), - f as *mut libc::c_void, - col, - istext, - text, - size, - ); -} - -pub unsafe fn mailmime_base64_write_mem( - mut f: *mut MMAPString, - mut col: *mut libc::c_int, - mut text: *const libc::c_char, - mut size: size_t, -) -> libc::c_int { - return mailmime_base64_write_driver(Some(do_write), f as *mut libc::c_void, col, text, size); -} - -pub unsafe fn mailmime_data_write_mem( - mut f: *mut MMAPString, - mut col: *mut libc::c_int, - mut data: *mut mailmime_data, - mut istext: libc::c_int, -) -> libc::c_int { - return mailmime_data_write_driver(Some(do_write), f as *mut libc::c_void, col, data, istext); -} diff --git a/mmime/src/mmapstring.rs b/mmime/src/mmapstring.rs deleted file mode 100644 index a3749ac4c..000000000 --- a/mmime/src/mmapstring.rs +++ /dev/null @@ -1,397 +0,0 @@ -use std::sync::Mutex; - -use lazy_static::lazy_static; -use libc; - -use crate::chash::*; -use crate::other::*; - -lazy_static! { - static ref mmapstring_lock: Mutex<()> = Mutex::new(()); -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct MMAPString { - pub str_0: *mut libc::c_char, - pub len: size_t, - pub allocated_len: size_t, - pub fd: libc::c_int, - pub mmapped_size: size_t, -} - -pub const TMPDIR: &'static str = "/tmp"; - -pub unsafe fn mmap_string_new(mut init: *const libc::c_char) -> *mut MMAPString { - let mut string: *mut MMAPString = 0 as *mut MMAPString; - string = mmap_string_sized_new(if !init.is_null() { - strlen(init).wrapping_add(2i32 as libc::size_t) - } else { - 2i32 as libc::size_t - }); - if string.is_null() { - return 0 as *mut MMAPString; - } - if !init.is_null() { - mmap_string_append(string, init); - } - return string; -} - -pub unsafe fn mmap_string_append( - mut string: *mut MMAPString, - mut val: *const libc::c_char, -) -> *mut MMAPString { - return mmap_string_insert_len(string, (*string).len, val, strlen(val)); -} - -pub unsafe fn mmap_string_insert_len( - mut string: *mut MMAPString, - mut pos: size_t, - mut val: *const libc::c_char, - mut len: size_t, -) -> *mut MMAPString { - if mmap_string_maybe_expand(string, len).is_null() { - return 0 as *mut MMAPString; - } - if pos < (*string).len { - memmove( - (*string).str_0.offset(pos as isize).offset(len as isize) as *mut libc::c_void, - (*string).str_0.offset(pos as isize) as *const libc::c_void, - (*string).len.wrapping_sub(pos), - ); - } - memmove( - (*string).str_0.offset(pos as isize) as *mut libc::c_void, - val as *const libc::c_void, - len, - ); - (*string).len = ((*string).len as libc::size_t).wrapping_add(len) as size_t as size_t; - *(*string).str_0.offset((*string).len as isize) = 0i32 as libc::c_char; - return string; -} -unsafe fn mmap_string_maybe_expand( - mut string: *mut MMAPString, - mut len: size_t, -) -> *mut MMAPString { - if (*string).len.wrapping_add(len) >= (*string).allocated_len { - let mut old_size: size_t = 0; - let mut newstring: *mut MMAPString = 0 as *mut MMAPString; - old_size = (*string).allocated_len; - (*string).allocated_len = nearest_power( - 1i32 as size_t, - (*string) - .len - .wrapping_add(len) - .wrapping_add(1i32 as libc::size_t), - ); - newstring = mmap_string_realloc_memory(string); - if newstring.is_null() { - (*string).allocated_len = old_size - } - return newstring; - } - return string; -} -/* Strings. - */ -/* SEB */ -unsafe fn mmap_string_realloc_memory(mut string: *mut MMAPString) -> *mut MMAPString { - let mut tmp: *mut libc::c_char = 0 as *mut libc::c_char; - tmp = realloc( - (*string).str_0 as *mut libc::c_void, - (*string).allocated_len, - ) as *mut libc::c_char; - if tmp.is_null() { - string = 0 as *mut MMAPString - } else { - (*string).str_0 = tmp - } - return string; -} -/* MMAPString */ -#[inline] -unsafe fn nearest_power(mut base: size_t, mut num: size_t) -> size_t { - if num > (-1i32 as size_t).wrapping_div(2i32 as libc::size_t) { - return -1i32 as size_t; - } else { - let mut n: size_t = base; - while n < num { - n <<= 1i32 - } - return n; - }; -} - -pub unsafe fn mmap_string_sized_new(mut dfl_size: size_t) -> *mut MMAPString { - let mut string: *mut MMAPString = 0 as *mut MMAPString; - string = malloc(::std::mem::size_of::() as libc::size_t) as *mut MMAPString; - if string.is_null() { - return 0 as *mut MMAPString; - } - (*string).allocated_len = 0i32 as size_t; - (*string).len = 0i32 as size_t; - (*string).str_0 = 0 as *mut libc::c_char; - (*string).fd = -1i32; - (*string).mmapped_size = 0i32 as size_t; - if mmap_string_maybe_expand( - string, - if dfl_size > 2i32 as libc::size_t { - dfl_size - } else { - 2i32 as libc::size_t - }, - ) - .is_null() - { - free(string as *mut libc::c_void); - return 0 as *mut MMAPString; - } - *(*string).str_0.offset(0isize) = 0i32 as libc::c_char; - return string; -} - -pub unsafe fn mmap_string_new_len( - mut init: *const libc::c_char, - mut len: size_t, -) -> *mut MMAPString { - let mut string: *mut MMAPString = 0 as *mut MMAPString; - if len <= 0i32 as libc::size_t { - return mmap_string_new(b"\x00" as *const u8 as *const libc::c_char); - } else { - string = mmap_string_sized_new(len); - if string.is_null() { - return string; - } - if !init.is_null() { - mmap_string_append_len(string, init, len); - } - return string; - }; -} - -pub unsafe fn mmap_string_append_len( - mut string: *mut MMAPString, - mut val: *const libc::c_char, - mut len: size_t, -) -> *mut MMAPString { - return mmap_string_insert_len(string, (*string).len, val, len); -} - -pub unsafe fn mmap_string_free(mut string: *mut MMAPString) { - if string.is_null() { - return; - } - free((*string).str_0 as *mut libc::c_void); - free(string as *mut libc::c_void); -} - -pub unsafe fn mmap_string_assign( - mut string: *mut MMAPString, - mut rval: *const libc::c_char, -) -> *mut MMAPString { - mmap_string_truncate(string, 0i32 as size_t); - if mmap_string_append(string, rval).is_null() { - return 0 as *mut MMAPString; - } - return string; -} - -pub unsafe fn mmap_string_truncate( - mut string: *mut MMAPString, - mut len: size_t, -) -> *mut MMAPString { - (*string).len = if len < (*string).len { - len - } else { - (*string).len - }; - *(*string).str_0.offset((*string).len as isize) = 0i32 as libc::c_char; - return string; -} - -pub unsafe fn mmap_string_set_size( - mut string: *mut MMAPString, - mut len: size_t, -) -> *mut MMAPString { - if len >= (*string).allocated_len { - if mmap_string_maybe_expand(string, len.wrapping_sub((*string).len)).is_null() { - return 0 as *mut MMAPString; - } - } - (*string).len = len; - *(*string).str_0.offset(len as isize) = 0i32 as libc::c_char; - return string; -} - -pub unsafe fn mmap_string_append_c( - mut string: *mut MMAPString, - mut c: libc::c_char, -) -> *mut MMAPString { - return mmap_string_insert_c(string, (*string).len, c); -} - -pub unsafe fn mmap_string_insert_c( - mut string: *mut MMAPString, - mut pos: size_t, - mut c: libc::c_char, -) -> *mut MMAPString { - if mmap_string_maybe_expand(string, 1i32 as size_t).is_null() { - return 0 as *mut MMAPString; - } - if pos < (*string).len { - memmove( - (*string).str_0.offset(pos as isize).offset(1isize) as *mut libc::c_void, - (*string).str_0.offset(pos as isize) as *const libc::c_void, - (*string).len.wrapping_sub(pos), - ); - } - *(*string).str_0.offset(pos as isize) = c; - (*string).len = - ((*string).len as libc::size_t).wrapping_add(1i32 as libc::size_t) as size_t as size_t; - *(*string).str_0.offset((*string).len as isize) = 0i32 as libc::c_char; - return string; -} - -pub unsafe fn mmap_string_prepend( - mut string: *mut MMAPString, - mut val: *const libc::c_char, -) -> *mut MMAPString { - return mmap_string_insert_len(string, 0i32 as size_t, val, strlen(val)); -} - -pub unsafe fn mmap_string_prepend_c( - mut string: *mut MMAPString, - mut c: libc::c_char, -) -> *mut MMAPString { - return mmap_string_insert_c(string, 0i32 as size_t, c); -} - -pub unsafe fn mmap_string_prepend_len( - mut string: *mut MMAPString, - mut val: *const libc::c_char, - mut len: size_t, -) -> *mut MMAPString { - return mmap_string_insert_len(string, 0i32 as size_t, val, len); -} - -pub unsafe fn mmap_string_insert( - mut string: *mut MMAPString, - mut pos: size_t, - mut val: *const libc::c_char, -) -> *mut MMAPString { - return mmap_string_insert_len(string, pos, val, strlen(val)); -} - -pub unsafe fn mmap_string_erase( - mut string: *mut MMAPString, - mut pos: size_t, - mut len: size_t, -) -> *mut MMAPString { - if pos.wrapping_add(len) < (*string).len { - memmove( - (*string).str_0.offset(pos as isize) as *mut libc::c_void, - (*string).str_0.offset(pos as isize).offset(len as isize) as *const libc::c_void, - (*string).len.wrapping_sub(pos.wrapping_add(len)), - ); - } - (*string).len = ((*string).len as libc::size_t).wrapping_sub(len) as size_t as size_t; - *(*string).str_0.offset((*string).len as isize) = 0i32 as libc::c_char; - return string; -} - -pub unsafe fn mmap_string_set_ceil(mut ceil: size_t) { - mmap_string_ceil = ceil; -} -static mut mmap_string_ceil: size_t = (8i32 * 1024i32 * 1024i32) as size_t; - -pub unsafe fn mmap_string_ref(mut string: *mut MMAPString) -> libc::c_int { - let mut ht: *mut chash = 0 as *mut chash; - let mut r: libc::c_int = 0; - let mut key: chashdatum = chashdatum { - data: 0 as *mut libc::c_void, - len: 0, - }; - let mut data: chashdatum = chashdatum { - data: 0 as *mut libc::c_void, - len: 0, - }; - mmapstring_lock.lock().unwrap(); - if mmapstring_hashtable.is_null() { - mmapstring_hashtable_init(); - } - ht = mmapstring_hashtable; - if ht.is_null() { - return -1i32; - } - key.data = &mut (*string).str_0 as *mut *mut libc::c_char as *mut libc::c_void; - key.len = ::std::mem::size_of::<*mut libc::c_char>() as libc::size_t as libc::c_uint; - data.data = string as *mut libc::c_void; - data.len = 0i32 as libc::c_uint; - r = chash_set( - mmapstring_hashtable, - &mut key, - &mut data, - 0 as *mut chashdatum, - ); - - if r < 0i32 { - return r; - } - return 0i32; -} - -static mut mmapstring_hashtable: *mut chash = 0 as *const chash as *mut chash; -unsafe fn mmapstring_hashtable_init() { - mmapstring_hashtable = chash_new(13i32 as libc::c_uint, 1i32); -} - -pub unsafe fn mmap_string_unref(mut str: *mut libc::c_char) -> libc::c_int { - let mut string: *mut MMAPString = 0 as *mut MMAPString; - let mut ht: *mut chash = 0 as *mut chash; - let mut key: chashdatum = chashdatum { - data: 0 as *mut libc::c_void, - len: 0, - }; - let mut data: chashdatum = chashdatum { - data: 0 as *mut libc::c_void, - len: 0, - }; - let mut r: libc::c_int = 0; - if str.is_null() { - return -1i32; - } - mmapstring_lock.lock().unwrap(); - ht = mmapstring_hashtable; - if ht.is_null() { - return -1i32; - } - key.data = &mut str as *mut *mut libc::c_char as *mut libc::c_void; - key.len = ::std::mem::size_of::<*mut libc::c_char>() as libc::size_t as libc::c_uint; - r = chash_get(ht, &mut key, &mut data); - if r < 0i32 { - string = 0 as *mut MMAPString - } else { - string = data.data as *mut MMAPString - } - if !string.is_null() { - chash_delete(ht, &mut key, 0 as *mut chashdatum); - if chash_count(ht) == 0i32 as libc::c_uint { - chash_free(ht); - mmapstring_hashtable = 0 as *mut chash - } - } - if !string.is_null() { - mmap_string_free(string); - return 0i32; - } else { - return -1i32; - }; -} -#[inline] -unsafe fn chash_count(mut hash: *mut chash) -> libc::c_uint { - return (*hash).count; -} - -pub unsafe fn mmapstring_init_lock() {} -pub unsafe fn mmapstring_uninit_lock() {} diff --git a/mmime/src/other.rs b/mmime/src/other.rs deleted file mode 100644 index 08d9162a5..000000000 --- a/mmime/src/other.rs +++ /dev/null @@ -1,1728 +0,0 @@ -use chrono::{Datelike, Local, TimeZone, Timelike}; - -use crate::clist::*; -use crate::mailimf::types::*; -use crate::mailimf::types_helper::*; -use crate::mailmime::types::*; -use crate::mailmime::types_helper::*; - -pub(crate) use libc::{ - calloc, close, free, isalpha, isdigit, malloc, memcmp, memcpy, memmove, memset, realloc, - strcpy, strlen, strncmp, strncpy, strnlen, -}; - -pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char) -> libc::c_int { - if s1.is_null() || s2.is_null() { - return 1; - } - - let s1 = std::ffi::CStr::from_ptr(s1) - .to_string_lossy() - .to_lowercase(); - let s2 = std::ffi::CStr::from_ptr(s2) - .to_string_lossy() - .to_lowercase(); - if s1 == s2 { - 0 - } else { - 1 - } -} - -pub(crate) unsafe fn strncasecmp( - s1: *const libc::c_char, - s2: *const libc::c_char, - n: libc::size_t, -) -> libc::c_int { - if s1.is_null() || s2.is_null() { - return 1; - } - - // s1 and s2 might not be null terminated. - - let s1_slice = - std::slice::from_raw_parts(s1 as *const u8, strnlen(s1 as *const libc::c_char, n)); - let s2_slice = - std::slice::from_raw_parts(s2 as *const u8, strnlen(s2 as *const libc::c_char, n)); - - let s1 = std::ffi::CStr::from_bytes_with_nul_unchecked(s1_slice) - .to_string_lossy() - .to_lowercase(); - let s2 = std::ffi::CStr::from_bytes_with_nul_unchecked(s2_slice) - .to_string_lossy() - .to_lowercase(); - - if s1 == s2 { - 0 - } else { - 1 - } -} - -pub(crate) unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char { - let slen = libc::strlen(s); - let result = libc::malloc(slen + 1); - if result.is_null() { - return std::ptr::null_mut(); - } - - libc::memcpy(result, s as *const _, slen + 1); - result as *mut _ -} - -pub(crate) type size_t = libc::size_t; -pub(crate) type uint32_t = libc::c_uint; - -pub const MAIL_ERROR_SSL: libc::c_uint = 58; -pub const MAIL_ERROR_FOLDER: libc::c_uint = 57; -pub const MAIL_ERROR_UNABLE: libc::c_uint = 56; -pub const MAIL_ERROR_SYSTEM: libc::c_uint = 55; -pub const MAIL_ERROR_COMMAND: libc::c_uint = 54; -pub const MAIL_ERROR_SEND: libc::c_uint = 53; -pub const MAIL_ERROR_CHAR_ENCODING_FAILED: libc::c_uint = 52; -pub const MAIL_ERROR_SUBJECT_NOT_FOUND: libc::c_uint = 51; -/* 50 */ -pub const MAIL_ERROR_PROGRAM_ERROR: libc::c_uint = 50; -pub const MAIL_ERROR_NO_PERMISSION: libc::c_uint = 49; -pub const MAIL_ERROR_COMMAND_NOT_SUPPORTED: libc::c_uint = 48; -pub const MAIL_ERROR_NO_APOP: libc::c_uint = 47; -pub const MAIL_ERROR_READONLY: libc::c_uint = 46; -pub const MAIL_ERROR_FATAL: libc::c_uint = 45; -pub const MAIL_ERROR_CLOSE: libc::c_uint = 44; -pub const MAIL_ERROR_CAPABILITY: libc::c_uint = 43; -pub const MAIL_ERROR_PROTOCOL: libc::c_uint = 42; -/* misc errors */ -pub const MAIL_ERROR_MISC: libc::c_uint = 41; -/* 40 */ -pub const MAIL_ERROR_EXPUNGE: libc::c_uint = 40; -pub const MAIL_ERROR_NO_TLS: libc::c_uint = 39; -pub const MAIL_ERROR_CACHE_MISS: libc::c_uint = 38; -pub const MAIL_ERROR_STARTTLS: libc::c_uint = 37; -pub const MAIL_ERROR_MOVE: libc::c_uint = 36; -pub const MAIL_ERROR_FOLDER_NOT_FOUND: libc::c_uint = 35; -pub const MAIL_ERROR_REMOVE: libc::c_uint = 34; -pub const MAIL_ERROR_PART_NOT_FOUND: libc::c_uint = 33; -pub const MAIL_ERROR_INVAL: libc::c_uint = 32; -pub const MAIL_ERROR_PARSE: libc::c_uint = 31; -/* 30 */ -pub const MAIL_ERROR_MSG_NOT_FOUND: libc::c_uint = 30; -pub const MAIL_ERROR_DISKSPACE: libc::c_uint = 29; -pub const MAIL_ERROR_SEARCH: libc::c_uint = 28; -pub const MAIL_ERROR_STORE: libc::c_uint = 27; -pub const MAIL_ERROR_FETCH: libc::c_uint = 26; -pub const MAIL_ERROR_COPY: libc::c_uint = 25; -pub const MAIL_ERROR_APPEND: libc::c_uint = 24; -pub const MAIL_ERROR_LSUB: libc::c_uint = 23; -pub const MAIL_ERROR_LIST: libc::c_uint = 22; -pub const MAIL_ERROR_UNSUBSCRIBE: libc::c_uint = 21; -/* 20 */ -pub const MAIL_ERROR_SUBSCRIBE: libc::c_uint = 20; -pub const MAIL_ERROR_STATUS: libc::c_uint = 19; -pub const MAIL_ERROR_MEMORY: libc::c_uint = 18; -pub const MAIL_ERROR_SELECT: libc::c_uint = 17; -pub const MAIL_ERROR_EXAMINE: libc::c_uint = 16; -pub const MAIL_ERROR_CHECK: libc::c_uint = 15; -pub const MAIL_ERROR_RENAME: libc::c_uint = 14; -pub const MAIL_ERROR_NOOP: libc::c_uint = 13; -pub const MAIL_ERROR_LOGOUT: libc::c_uint = 12; -pub const MAIL_ERROR_DELETE: libc::c_uint = 11; -/* 10 */ -pub const MAIL_ERROR_CREATE: libc::c_uint = 10; -pub const MAIL_ERROR_LOGIN: libc::c_uint = 9; -pub const MAIL_ERROR_STREAM: libc::c_uint = 8; -pub const MAIL_ERROR_FILE: libc::c_uint = 7; -pub const MAIL_ERROR_BAD_STATE: libc::c_uint = 6; -pub const MAIL_ERROR_CONNECT: libc::c_uint = 5; -pub const MAIL_ERROR_UNKNOWN: libc::c_uint = 4; -pub const MAIL_ERROR_NOT_IMPLEMENTED: libc::c_uint = 3; -pub const MAIL_NO_ERROR_NON_AUTHENTICATED: libc::c_uint = 2; -pub const MAIL_NO_ERROR_AUTHENTICATED: libc::c_uint = 1; -pub const MAIL_NO_ERROR: libc::c_uint = 0; - -pub const MAILIMF_ERROR_FILE: libc::c_uint = 4; -pub const MAILIMF_ERROR_INVAL: libc::c_uint = 3; -pub const MAILIMF_ERROR_MEMORY: libc::c_uint = 2; -pub const MAILIMF_ERROR_PARSE: libc::c_uint = 1; -pub const MAILIMF_NO_ERROR: libc::c_uint = 0; - -pub unsafe fn mailprivacy_prepare_mime(mut mime: *mut Mailmime) { - let mut cur: *mut clistiter = 0 as *mut clistiter; - match (*mime).mm_type { - 1 => { - if !(*mime).mm_data.mm_single.is_null() { - prepare_mime_single(mime); - } - } - 2 => { - cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first; - while !cur.is_null() { - let mut child: *mut Mailmime = 0 as *mut Mailmime; - child = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut Mailmime; - mailprivacy_prepare_mime(child); - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } - } - } - 3 => { - if !(*mime).mm_data.mm_message.mm_msg_mime.is_null() { - mailprivacy_prepare_mime((*mime).mm_data.mm_message.mm_msg_mime); - } - } - _ => {} - }; -} - -unsafe fn prepare_mime_single(mut mime: *mut Mailmime) { - let mut single_fields: mailmime_single_fields = mailmime_single_fields { - fld_content: 0 as *mut mailmime_content, - fld_content_charset: 0 as *mut libc::c_char, - fld_content_boundary: 0 as *mut libc::c_char, - fld_content_name: 0 as *mut libc::c_char, - fld_encoding: 0 as *mut mailmime_mechanism, - fld_id: 0 as *mut libc::c_char, - fld_description: 0 as *mut libc::c_char, - fld_version: 0, - fld_disposition: 0 as *mut mailmime_disposition, - fld_disposition_filename: 0 as *mut libc::c_char, - fld_disposition_creation_date: 0 as *mut libc::c_char, - fld_disposition_modification_date: 0 as *mut libc::c_char, - fld_disposition_read_date: 0 as *mut libc::c_char, - fld_disposition_size: 0, - fld_language: 0 as *mut mailmime_language, - fld_location: 0 as *mut libc::c_char, - }; - let mut encoding: libc::c_int = 0; - let mut r: libc::c_int = 0; - if !(*mime).mm_mime_fields.is_null() { - mailmime_single_fields_init( - &mut single_fields, - (*mime).mm_mime_fields, - (*mime).mm_content_type, - ); - if !single_fields.fld_encoding.is_null() { - encoding = (*single_fields.fld_encoding).enc_type; - match encoding { - 2 | 1 | 3 => { - (*single_fields.fld_encoding).enc_type = - MAILMIME_MECHANISM_QUOTED_PRINTABLE as libc::c_int - } - _ => {} - } - } else { - let mut mechanism: *mut mailmime_mechanism = 0 as *mut mailmime_mechanism; - let mut field: *mut mailmime_field = 0 as *mut mailmime_field; - mechanism = mailmime_mechanism_new( - MAILMIME_MECHANISM_QUOTED_PRINTABLE as libc::c_int, - 0 as *mut libc::c_char, - ); - if mechanism.is_null() { - return; - } - field = mailmime_field_new( - MAILMIME_FIELD_TRANSFER_ENCODING as libc::c_int, - 0 as *mut mailmime_content, - mechanism, - 0 as *mut libc::c_char, - 0 as *mut libc::c_char, - 0i32 as uint32_t, - 0 as *mut mailmime_disposition, - 0 as *mut mailmime_language, - 0 as *mut libc::c_char, - ); - if field.is_null() { - mailmime_mechanism_free(mechanism); - return; - } - r = clist_insert_after( - (*(*mime).mm_mime_fields).fld_list, - (*(*(*mime).mm_mime_fields).fld_list).last, - field as *mut libc::c_void, - ); - if r < 0i32 { - mailmime_field_free(field); - return; - } - } - } - if (*mime).mm_type == MAILMIME_SINGLE as libc::c_int { - match (*(*mime).mm_data.mm_single).dt_encoding { - 2 | 1 | 3 => { - (*(*mime).mm_data.mm_single).dt_encoding = - MAILMIME_MECHANISM_QUOTED_PRINTABLE as libc::c_int; - (*(*mime).mm_data.mm_single).dt_encoded = 0i32 - } - _ => {} - } - }; -} - -pub unsafe fn mailmime_substitute( - mut old_mime: *mut Mailmime, - mut new_mime: *mut Mailmime, -) -> libc::c_int { - let mut parent: *mut Mailmime = 0 as *mut Mailmime; - parent = (*old_mime).mm_parent; - if parent.is_null() { - return MAIL_ERROR_INVAL as libc::c_int; - } - if (*old_mime).mm_parent_type == MAILMIME_MESSAGE as libc::c_int { - (*parent).mm_data.mm_message.mm_msg_mime = new_mime - } else { - (*(*old_mime).mm_multipart_pos).data = new_mime as *mut libc::c_void - } - (*new_mime).mm_parent = parent; - (*new_mime).mm_parent_type = (*old_mime).mm_parent_type; - (*old_mime).mm_parent = 0 as *mut Mailmime; - (*old_mime).mm_parent_type = MAILMIME_NONE as libc::c_int; - return MAIL_NO_ERROR as libc::c_int; -} - -/* - mailimf_address_list_new_empty creates an empty list of addresses -*/ -pub unsafe fn mailimf_address_list_new_empty() -> *mut mailimf_address_list { - let mut list: *mut clist = 0 as *mut clist; - let mut addr_list: *mut mailimf_address_list = 0 as *mut mailimf_address_list; - list = clist_new(); - if list.is_null() { - return 0 as *mut mailimf_address_list; - } - addr_list = mailimf_address_list_new(list); - if addr_list.is_null() { - return 0 as *mut mailimf_address_list; - } - return addr_list; -} - -/* - mailimf_mailbox_list_new_empty creates an empty list of mailboxes -*/ -pub unsafe fn mailimf_mailbox_list_new_empty() -> *mut mailimf_mailbox_list { - let mut list: *mut clist = 0 as *mut clist; - let mut mb_list: *mut mailimf_mailbox_list = 0 as *mut mailimf_mailbox_list; - list = clist_new(); - if list.is_null() { - return 0 as *mut mailimf_mailbox_list; - } - mb_list = mailimf_mailbox_list_new(list); - if mb_list.is_null() { - return 0 as *mut mailimf_mailbox_list; - } - return mb_list; -} - -/* - mailimf_mailbox_list_add adds a mailbox to the list of mailboxes - - @return MAILIMF_NO_ERROR will be returned on success, - other code will be returned otherwise -*/ -pub unsafe fn mailimf_mailbox_list_add( - mut mailbox_list: *mut mailimf_mailbox_list, - mut mb: *mut mailimf_mailbox, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = clist_insert_after( - (*mailbox_list).mb_list, - (*(*mailbox_list).mb_list).last, - mb as *mut libc::c_void, - ); - if r < 0i32 { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - return MAILIMF_NO_ERROR as libc::c_int; -} - -/* - mailimf_address_list_add adds a mailbox to the list of addresses - - @return MAILIMF_NO_ERROR will be returned on success, - other code will be returned otherwise -*/ -pub unsafe fn mailimf_address_list_add( - mut address_list: *mut mailimf_address_list, - mut addr: *mut mailimf_address, -) -> libc::c_int { - let mut r: libc::c_int = 0; - r = clist_insert_after( - (*address_list).ad_list, - (*(*address_list).ad_list).last, - addr as *mut libc::c_void, - ); - if r < 0i32 { - return MAILIMF_ERROR_MEMORY as libc::c_int; - } - return MAILIMF_NO_ERROR as libc::c_int; -} - -/* - mailimf_fields_new_with_data_all creates a new mailimf_fields - structure with a set of fields - - if you don't want a given field in the set to be added in the list - of fields, you can give NULL as argument - - @param message_id sould be allocated with malloc() - @param subject should be allocated with malloc() - @param in_reply_to each elements of this list should be allocated - with malloc() - @param references each elements of this list should be allocated - with malloc() - - @return MAILIMF_NO_ERROR will be returned on success, - other code will be returned otherwise -*/ -pub unsafe fn mailimf_fields_new_with_data_all( - mut date: *mut mailimf_date_time, - mut from: *mut mailimf_mailbox_list, - mut sender: *mut mailimf_mailbox, - mut reply_to: *mut mailimf_address_list, - mut to: *mut mailimf_address_list, - mut cc: *mut mailimf_address_list, - mut bcc: *mut mailimf_address_list, - mut message_id: *mut libc::c_char, - mut in_reply_to: *mut clist, - mut references: *mut clist, - mut subject: *mut libc::c_char, -) -> *mut mailimf_fields { - let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; - let mut r: libc::c_int = 0; - fields = mailimf_fields_new_empty(); - if !fields.is_null() { - r = mailimf_fields_add_data( - fields, - date, - from, - sender, - reply_to, - to, - cc, - bcc, - message_id, - in_reply_to, - references, - subject, - ); - if r != MAILIMF_NO_ERROR as libc::c_int { - mailimf_fields_free(fields); - } else { - return fields; - } - } - return 0 as *mut mailimf_fields; -} - -/* - mailimf_fields_add_data adds a set of fields in the - given mailimf_fields structure. - - if you don't want a given field in the set to be added in the list - of fields, you can give NULL as argument - - @param msg_id sould be allocated with malloc() - @param subject should be allocated with malloc() - @param in_reply_to each elements of this list should be allocated - with malloc() - @param references each elements of this list should be allocated - with malloc() - - @return MAILIMF_NO_ERROR will be returned on success, - other code will be returned otherwise -*/ -pub unsafe fn mailimf_fields_add_data( - mut fields: *mut mailimf_fields, - mut date: *mut mailimf_date_time, - mut from: *mut mailimf_mailbox_list, - mut sender: *mut mailimf_mailbox, - mut reply_to: *mut mailimf_address_list, - mut to: *mut mailimf_address_list, - mut cc: *mut mailimf_address_list, - mut bcc: *mut mailimf_address_list, - mut msg_id: *mut libc::c_char, - mut in_reply_to: *mut clist, - mut references: *mut clist, - mut subject: *mut libc::c_char, -) -> libc::c_int { - let mut current_block: u64; - let mut imf_date: *mut mailimf_orig_date = 0 as *mut mailimf_orig_date; - let mut imf_from: *mut mailimf_from = 0 as *mut mailimf_from; - let mut imf_sender: *mut mailimf_sender = 0 as *mut mailimf_sender; - let mut imf_reply_to: *mut mailimf_reply_to = 0 as *mut mailimf_reply_to; - let mut imf_to: *mut mailimf_to = 0 as *mut mailimf_to; - let mut imf_cc: *mut mailimf_cc = 0 as *mut mailimf_cc; - let mut imf_bcc: *mut mailimf_bcc = 0 as *mut mailimf_bcc; - let mut imf_msg_id: *mut mailimf_message_id = 0 as *mut mailimf_message_id; - let mut imf_references: *mut mailimf_references = 0 as *mut mailimf_references; - let mut imf_in_reply_to: *mut mailimf_in_reply_to = 0 as *mut mailimf_in_reply_to; - let mut imf_subject: *mut mailimf_subject = 0 as *mut mailimf_subject; - let mut field: *mut mailimf_field = 0 as *mut mailimf_field; - let mut r: libc::c_int = 0; - imf_date = 0 as *mut mailimf_orig_date; - imf_from = 0 as *mut mailimf_from; - imf_sender = 0 as *mut mailimf_sender; - imf_reply_to = 0 as *mut mailimf_reply_to; - imf_to = 0 as *mut mailimf_to; - imf_cc = 0 as *mut mailimf_cc; - imf_bcc = 0 as *mut mailimf_bcc; - imf_msg_id = 0 as *mut mailimf_message_id; - imf_references = 0 as *mut mailimf_references; - imf_in_reply_to = 0 as *mut mailimf_in_reply_to; - imf_subject = 0 as *mut mailimf_subject; - field = 0 as *mut mailimf_field; - if !date.is_null() { - imf_date = mailimf_orig_date_new(date); - if imf_date.is_null() { - current_block = 16539016819803454162; - } else { - field = mailimf_field_new( - MAILIMF_FIELD_ORIG_DATE as libc::c_int, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - imf_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_reply_to, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_in_reply_to, - 0 as *mut mailimf_references, - 0 as *mut mailimf_subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - 0 as *mut mailimf_optional_field, - ); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field.is_null() { - current_block = 16539016819803454162; - } else { - r = mailimf_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 13813460800808168376; - } else { - current_block = 2719512138335094285; - } - } - } - } else { - current_block = 2719512138335094285; - } - match current_block { - 2719512138335094285 => { - if !from.is_null() { - imf_from = mailimf_from_new(from); - if imf_from.is_null() { - current_block = 13813460800808168376; - } else { - field = mailimf_field_new( - MAILIMF_FIELD_FROM as libc::c_int, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_orig_date, - imf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_reply_to, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_in_reply_to, - 0 as *mut mailimf_references, - 0 as *mut mailimf_subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - 0 as *mut mailimf_optional_field, - ); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field.is_null() { - current_block = 16539016819803454162; - } else { - r = mailimf_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 13813460800808168376; - } else { - current_block = 3275366147856559585; - } - } - } - } else { - current_block = 3275366147856559585; - } - match current_block { - 13813460800808168376 => {} - 16539016819803454162 => {} - _ => { - if !sender.is_null() { - imf_sender = mailimf_sender_new(sender); - if imf_sender.is_null() { - current_block = 16539016819803454162; - } else { - field = mailimf_field_new( - MAILIMF_FIELD_SENDER as libc::c_int, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - imf_sender, - 0 as *mut mailimf_reply_to, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_in_reply_to, - 0 as *mut mailimf_references, - 0 as *mut mailimf_subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - 0 as *mut mailimf_optional_field, - ); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field.is_null() { - current_block = 16539016819803454162; - } else { - r = mailimf_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 13813460800808168376; - } else { - current_block = 15090052786889560393; - } - } - } - } else { - current_block = 15090052786889560393; - } - match current_block { - 16539016819803454162 => {} - 13813460800808168376 => {} - _ => { - if !reply_to.is_null() { - imf_reply_to = mailimf_reply_to_new(reply_to); - if imf_reply_to.is_null() { - current_block = 16539016819803454162; - } else { - field = mailimf_field_new( - MAILIMF_FIELD_REPLY_TO as libc::c_int, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - imf_reply_to, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_in_reply_to, - 0 as *mut mailimf_references, - 0 as *mut mailimf_subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - 0 as *mut mailimf_optional_field, - ); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field.is_null() { - current_block = 16539016819803454162; - } else { - r = mailimf_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 13813460800808168376; - } else { - current_block = 10150597327160359210; - } - } - } - } else { - current_block = 10150597327160359210; - } - match current_block { - 16539016819803454162 => {} - 13813460800808168376 => {} - _ => { - if !to.is_null() { - imf_to = mailimf_to_new(to); - if imf_to.is_null() { - current_block = 16539016819803454162; - } else { - field = mailimf_field_new( - MAILIMF_FIELD_TO as libc::c_int, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_reply_to, - imf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_in_reply_to, - 0 as *mut mailimf_references, - 0 as *mut mailimf_subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - 0 as *mut mailimf_optional_field, - ); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field.is_null() { - current_block = 16539016819803454162; - } else { - r = mailimf_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 13813460800808168376; - } else { - current_block = 17233182392562552756; - } - } - } - } else { - current_block = 17233182392562552756; - } - match current_block { - 16539016819803454162 => {} - 13813460800808168376 => {} - _ => { - if !cc.is_null() { - imf_cc = mailimf_cc_new(cc); - if imf_cc.is_null() { - current_block = 16539016819803454162; - } else { - field = mailimf_field_new( - MAILIMF_FIELD_CC as libc::c_int, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_reply_to, - 0 as *mut mailimf_to, - imf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_in_reply_to, - 0 as *mut mailimf_references, - 0 as *mut mailimf_subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - 0 as *mut mailimf_optional_field, - ); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field.is_null() { - current_block = 16539016819803454162; - } else { - r = mailimf_fields_add(fields, field); - if r != MAILIMF_NO_ERROR as libc::c_int { - current_block = 13813460800808168376; - } else { - current_block = 12930649117290160518; - } - } - } - } else { - current_block = 12930649117290160518; - } - match current_block { - 16539016819803454162 => {} - 13813460800808168376 => {} - _ => { - if !bcc.is_null() { - imf_bcc = mailimf_bcc_new(bcc); - if imf_bcc.is_null() { - current_block = 16539016819803454162; - } else { - field = mailimf_field_new( - MAILIMF_FIELD_BCC as libc::c_int, - 0 as *mut mailimf_return, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - 0 as *mut mailimf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_orig_date, - 0 as *mut mailimf_from, - 0 as *mut mailimf_sender, - 0 as *mut mailimf_reply_to, - 0 as *mut mailimf_to, - 0 as *mut mailimf_cc, - imf_bcc, - 0 as *mut mailimf_message_id, - 0 as *mut mailimf_in_reply_to, - 0 as *mut mailimf_references, - 0 as *mut mailimf_subject, - 0 as *mut mailimf_comments, - 0 as *mut mailimf_keywords, - 0 as *mut mailimf_optional_field, - ); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field.is_null() { - current_block = - 16539016819803454162; - } else { - r = mailimf_fields_add( - fields, field, - ); - if r != MAILIMF_NO_ERROR - as libc::c_int - { - current_block = - 13813460800808168376; - } else { - current_block = - 7858101417678297991; - } - } - } - } else { - current_block = 7858101417678297991; - } - match current_block { - 16539016819803454162 => {} - 13813460800808168376 => {} - _ => { - if !msg_id.is_null() { - imf_msg_id = - mailimf_message_id_new(msg_id); - if imf_msg_id.is_null() { - current_block = - 16539016819803454162; - } else { - field = - mailimf_field_new(MAILIMF_FIELD_MESSAGE_ID - as - libc::c_int, - 0 - as - *mut mailimf_return, - 0 - as - *mut mailimf_orig_date, - 0 - as - *mut mailimf_from, - 0 - as - *mut mailimf_sender, - 0 - as - *mut mailimf_to, - 0 - as - *mut mailimf_cc, - 0 - as - *mut mailimf_bcc, - 0 - as - *mut mailimf_message_id, - 0 - as - *mut mailimf_orig_date, - 0 - as - *mut mailimf_from, - 0 - as - *mut mailimf_sender, - 0 - as - *mut mailimf_reply_to, - 0 - as - *mut mailimf_to, - 0 - as - *mut mailimf_cc, - 0 - as - *mut mailimf_bcc, - imf_msg_id, - 0 - as - *mut mailimf_in_reply_to, - 0 - as - *mut mailimf_references, - 0 - as - *mut mailimf_subject, - 0 - as - *mut mailimf_comments, - 0 - as - *mut mailimf_keywords, - 0 - as - *mut mailimf_optional_field); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field.is_null() { - current_block = - 16539016819803454162; - } else { - r = mailimf_fields_add( - fields, field, - ); - if r != MAILIMF_NO_ERROR - as libc::c_int - { - current_block - = - 13813460800808168376; - } else { - current_block - = - 15514718523126015390; - } - } - } - } else { - current_block = - 15514718523126015390; - } - match current_block { - 13813460800808168376 => {} - 16539016819803454162 => {} - _ => { - if !in_reply_to.is_null() { - imf_in_reply_to = - mailimf_in_reply_to_new( - in_reply_to, - ); - if imf_in_reply_to.is_null() - { - current_block - = - 16539016819803454162; - } else { - field - = - mailimf_field_new(MAILIMF_FIELD_IN_REPLY_TO - as - libc::c_int, - 0 - as - *mut mailimf_return, - 0 - as - *mut mailimf_orig_date, - 0 - as - *mut mailimf_from, - 0 - as - *mut mailimf_sender, - 0 - as - *mut mailimf_to, - 0 - as - *mut mailimf_cc, - 0 - as - *mut mailimf_bcc, - 0 - as - *mut mailimf_message_id, - 0 - as - *mut mailimf_orig_date, - 0 - as - *mut mailimf_from, - 0 - as - *mut mailimf_sender, - 0 - as - *mut mailimf_reply_to, - 0 - as - *mut mailimf_to, - 0 - as - *mut mailimf_cc, - 0 - as - *mut mailimf_bcc, - 0 - as - *mut mailimf_message_id, - imf_in_reply_to, - 0 - as - *mut mailimf_references, - 0 - as - *mut mailimf_subject, - 0 - as - *mut mailimf_comments, - 0 - as - *mut mailimf_keywords, - 0 - as - *mut mailimf_optional_field); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field.is_null() { - current_block - = - 16539016819803454162; - } else { - r - = - mailimf_fields_add(fields, - field); - if r - != - MAILIMF_NO_ERROR - as - libc::c_int - { - current_block - = - 13813460800808168376; - } else { - current_block - = - 15587532755333643506; - } - } - } - } else { - current_block = - 15587532755333643506; - } - match current_block { - 13813460800808168376 => {} - 16539016819803454162 => {} - _ => { - if !references.is_null() - { - imf_references - = - mailimf_references_new(references); - if imf_references - .is_null() - { - current_block - = - 16539016819803454162; - } else { - field - = - mailimf_field_new(MAILIMF_FIELD_REFERENCES - as - libc::c_int, - 0 - as - *mut mailimf_return, - 0 - as - *mut mailimf_orig_date, - 0 - as - *mut mailimf_from, - 0 - as - *mut mailimf_sender, - 0 - as - *mut mailimf_to, - 0 - as - *mut mailimf_cc, - 0 - as - *mut mailimf_bcc, - 0 - as - *mut mailimf_message_id, - 0 - as - *mut mailimf_orig_date, - 0 - as - *mut mailimf_from, - 0 - as - *mut mailimf_sender, - 0 - as - *mut mailimf_reply_to, - 0 - as - *mut mailimf_to, - 0 - as - *mut mailimf_cc, - 0 - as - *mut mailimf_bcc, - 0 - as - *mut mailimf_message_id, - 0 - as - *mut mailimf_in_reply_to, - imf_references, - 0 - as - *mut mailimf_subject, - 0 - as - *mut mailimf_comments, - 0 - as - *mut mailimf_keywords, - 0 - as - *mut mailimf_optional_field); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field - .is_null() - { - current_block - = - 16539016819803454162; - } else { - r - = - mailimf_fields_add(fields, - field); - if r - != - MAILIMF_NO_ERROR - as - libc::c_int - { - current_block - = - 13813460800808168376; - } else { - current_block - = - 7301440000599063274; - } - } - } - } else { - current_block - = - 7301440000599063274; - } - match current_block - { - 13813460800808168376 - => - { - } - 16539016819803454162 - => - { - } - _ - => - { - if !subject.is_null() - { - imf_subject - = - mailimf_subject_new(subject); - if imf_subject.is_null() - { - current_block - = - 16539016819803454162; - } else { - field - = - mailimf_field_new(MAILIMF_FIELD_SUBJECT - as - libc::c_int, - 0 - as - *mut mailimf_return, - 0 - as - *mut mailimf_orig_date, - 0 - as - *mut mailimf_from, - 0 - as - *mut mailimf_sender, - 0 - as - *mut mailimf_to, - 0 - as - *mut mailimf_cc, - 0 - as - *mut mailimf_bcc, - 0 - as - *mut mailimf_message_id, - 0 - as - *mut mailimf_orig_date, - 0 - as - *mut mailimf_from, - 0 - as - *mut mailimf_sender, - 0 - as - *mut mailimf_reply_to, - 0 - as - *mut mailimf_to, - 0 - as - *mut mailimf_cc, - 0 - as - *mut mailimf_bcc, - 0 - as - *mut mailimf_message_id, - 0 - as - *mut mailimf_in_reply_to, - 0 - as - *mut mailimf_references, - imf_subject, - 0 - as - *mut mailimf_comments, - 0 - as - *mut mailimf_keywords, - 0 - as - *mut mailimf_optional_field); - /* return-path */ - /* resent date */ - /* resent from */ - /* resent sender */ - /* resent to */ - /* resent cc */ - /* resent bcc */ - /* resent msg id */ - /* date */ - /* from */ - /* sender */ - /* reply-to */ - /* to */ - /* cc */ - /* bcc */ - /* message id */ - /* in reply to */ - /* references */ - /* subject */ - /* comments */ - /* keywords */ - /* optional field */ - if field.is_null() - { - current_block - = - 16539016819803454162; - } else { - r - = - mailimf_fields_add(fields, - field); - if r - != - MAILIMF_NO_ERROR - as - libc::c_int - { - current_block - = - 13813460800808168376; - } else { - current_block - = - 10153752038087260855; - } - } - } - } else { - current_block - = - 10153752038087260855; - } - match current_block - { - 13813460800808168376 - => - { - } - 16539016819803454162 - => - { - } - _ - => - { - return MAILIMF_NO_ERROR - as - libc::c_int - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - _ => {} - } - match current_block { - 13813460800808168376 => { - if !field.is_null() { - detach_field(field); - mailimf_field_free(field); - } - } - _ => {} - } - detach_free_fields( - imf_date, - imf_from, - imf_sender, - imf_reply_to, - imf_to, - imf_cc, - imf_bcc, - imf_msg_id, - imf_in_reply_to, - imf_references, - imf_subject, - ); - return MAILIMF_ERROR_MEMORY as libc::c_int; -} - -unsafe fn detach_free_fields( - mut date: *mut mailimf_orig_date, - mut from: *mut mailimf_from, - mut sender: *mut mailimf_sender, - mut reply_to: *mut mailimf_reply_to, - mut to: *mut mailimf_to, - mut cc: *mut mailimf_cc, - mut bcc: *mut mailimf_bcc, - mut msg_id: *mut mailimf_message_id, - mut in_reply_to: *mut mailimf_in_reply_to, - mut references: *mut mailimf_references, - mut subject: *mut mailimf_subject, -) { - detach_free_common_fields(date, from, sender, to, cc, bcc, msg_id); - if !reply_to.is_null() { - (*reply_to).rt_addr_list = 0 as *mut mailimf_address_list; - mailimf_reply_to_free(reply_to); - } - if !in_reply_to.is_null() { - (*in_reply_to).mid_list = 0 as *mut clist; - mailimf_in_reply_to_free(in_reply_to); - } - if !references.is_null() { - (*references).mid_list = 0 as *mut clist; - mailimf_references_free(references); - } - if !subject.is_null() { - (*subject).sbj_value = 0 as *mut libc::c_char; - mailimf_subject_free(subject); - }; -} - -unsafe fn detach_field(mut field: *mut mailimf_field) { - (*field).fld_type = MAILIMF_FIELD_NONE as libc::c_int; - mailimf_field_free(field); -} - -unsafe fn detach_free_common_fields( - mut imf_date: *mut mailimf_orig_date, - mut imf_from: *mut mailimf_from, - mut imf_sender: *mut mailimf_sender, - mut imf_to: *mut mailimf_to, - mut imf_cc: *mut mailimf_cc, - mut imf_bcc: *mut mailimf_bcc, - mut imf_msg_id: *mut mailimf_message_id, -) { - if !imf_date.is_null() { - (*imf_date).dt_date_time = 0 as *mut mailimf_date_time; - mailimf_orig_date_free(imf_date); - } - if !imf_from.is_null() { - (*imf_from).frm_mb_list = 0 as *mut mailimf_mailbox_list; - mailimf_from_free(imf_from); - } - if !imf_sender.is_null() { - (*imf_sender).snd_mb = 0 as *mut mailimf_mailbox; - mailimf_sender_free(imf_sender); - } - if !imf_to.is_null() { - (*imf_to).to_addr_list = 0 as *mut mailimf_address_list; - mailimf_to_free(imf_to); - } - if !imf_cc.is_null() { - (*imf_cc).cc_addr_list = 0 as *mut mailimf_address_list; - mailimf_to_free(imf_to); - } - if !imf_bcc.is_null() { - (*imf_bcc).bcc_addr_list = 0 as *mut mailimf_address_list; - mailimf_bcc_free(imf_bcc); - } - if !imf_msg_id.is_null() { - (*imf_msg_id).mid_value = 0 as *mut libc::c_char; - mailimf_message_id_free(imf_msg_id); - }; -} - -pub fn mailimf_get_date(t: i64) -> *mut mailimf_date_time { - let lt = Local.timestamp(t, 0); - - let off = (lt.offset().local_minus_utc() / (60 * 60)) * 100; - - unsafe { - mailimf_date_time_new( - lt.day() as libc::c_int, - lt.month() as libc::c_int, - lt.year() as libc::c_int, - lt.hour() as libc::c_int, - lt.minute() as libc::c_int, - lt.second() as libc::c_int, - off, - ) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use chrono::Utc; - use std::ffi::CString; - - #[test] - fn test_strcasecmp() { - assert_eq!(0, unsafe { - strcasecmp( - CString::new("hello").unwrap().as_ptr(), - CString::new("Hello").unwrap().as_ptr(), - ) - }); - } - - #[test] - fn test_strncasecmp() { - assert_eq!(0, unsafe { - strncasecmp( - CString::new("helloworld").unwrap().as_ptr(), - CString::new("Helloward").unwrap().as_ptr(), - 4, - ) - }); - - assert_eq!(0, unsafe { - strncasecmp( - CString::new("hell").unwrap().as_ptr(), - CString::new("Hell").unwrap().as_ptr(), - 100_000_000, - ) - }); - } - - #[test] - fn test_get_date() { - let now_utc = Utc::now(); - - let now_local = Local.from_utc_datetime(&now_utc.naive_local()); - let t_local = now_local.timestamp(); - - let converted = unsafe { *mailimf_get_date(t_local as i64) }; - - assert_eq!(converted.dt_day as u32, now_local.day()); - assert_eq!(converted.dt_month as u32, now_local.month()); - assert_eq!(converted.dt_year, now_local.year()); - assert_eq!(converted.dt_hour as u32, now_local.hour()); - assert_eq!(converted.dt_min as u32, now_local.minute()); - assert_eq!(converted.dt_sec as u32, now_local.second()); - assert_eq!( - converted.dt_zone, - (now_local.offset().local_minus_utc() / (60 * 60)) * 100 - ); - } -} diff --git a/src/aheader.rs b/src/aheader.rs index 47e374aef..22b03102f 100644 --- a/src/aheader.rs +++ b/src/aheader.rs @@ -3,14 +3,12 @@ //! Parse and create [Autocrypt-headers](https://autocrypt.org/en/latest/level1.html#the-autocrypt-header). use std::collections::BTreeMap; -use std::ffi::CStr; use std::str::FromStr; use std::{fmt, str}; -use mmime::mailimf::types::*; - use crate::constants::*; use crate::contact::*; +use crate::context::Context; use crate::key::*; /// Possible values for encryption preference @@ -68,45 +66,31 @@ impl Aheader { } } - pub fn from_imffields(wanted_from: &str, header: *const mailimf_fields) -> Option { - if header.is_null() { - return None; - } + pub fn from_headers( + context: &Context, + wanted_from: &str, + headers: &[mailparse::MailHeader<'_>], + ) -> Option { + use mailparse::MailHeaderMap; - let mut fine_header = None; - let mut cur = unsafe { (*(*header).fld_list).first }; - - while !cur.is_null() { - let field = unsafe { (*cur).data as *mut mailimf_field }; - if !field.is_null() - && unsafe { (*field).fld_type } == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int - { - let optional_field = unsafe { (*field).fld_data.fld_optional_field }; - if !optional_field.is_null() - && unsafe { !(*optional_field).fld_name.is_null() } - && unsafe { CStr::from_ptr((*optional_field).fld_name).to_string_lossy() } - == "Autocrypt" - { - let value = - unsafe { CStr::from_ptr((*optional_field).fld_value).to_string_lossy() }; - - if let Ok(test) = Self::from_str(&value) { - if addr_cmp(&test.addr, wanted_from) { - if fine_header.is_none() { - fine_header = Some(test); - } else { - // TODO: figure out what kind of error case this is - return None; - } - } + if let Ok(Some(value)) = headers.get_first_value("Autocrypt") { + match Self::from_str(&value) { + Ok(header) => { + info!(context, "comparing {} - {}", header.addr, wanted_from); + if addr_cmp(&header.addr, wanted_from) { + return Some(header); } } + Err(err) => { + warn!( + context, + "found invalid autocrypt header {}: {:?}", value, err + ); + } } - - cur = unsafe { (*cur).next }; } - fine_header + None } } diff --git a/src/chat.rs b/src/chat.rs index 0a35742d8..dedb2b0e6 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -11,12 +11,12 @@ use crate::config::*; use crate::constants::*; use crate::contact::*; use crate::context::Context; -use crate::dc_mimeparser::SystemMessage; use crate::dc_tools::*; use crate::error::Error; use crate::events::Event; use crate::job::*; use crate::message::{self, InvalidMsgId, Message, MessageState, MsgId}; +use crate::mimeparser::SystemMessage; use crate::param::*; use crate::sql::{self, Sql}; use crate::stock::StockMessage; diff --git a/src/context.rs b/src/context.rs index 6515b1842..711e34be1 100644 --- a/src/context.rs +++ b/src/context.rs @@ -86,7 +86,7 @@ pub fn get_info() -> HashMap<&'static str, String> { ); res.insert( "arch", - (::std::mem::size_of::<*mut libc::c_void>()) + (std::mem::size_of::<*mut libc::c_void>()) .wrapping_mul(8) .to_string(), ); diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs deleted file mode 100644 index fc264ace5..000000000 --- a/src/dc_mimeparser.rs +++ /dev/null @@ -1,1312 +0,0 @@ -use std::collections::{HashMap, HashSet}; -use std::ffi::{CStr, CString}; -use std::ptr; - -use charset::Charset; -use deltachat_derive::{FromSql, ToSql}; -use libc::{strcmp, strlen, strncmp}; -use mmime::mailimf::types::*; -use mmime::mailimf::*; -use mmime::mailmime::content::*; -use mmime::mailmime::disposition::*; -use mmime::mailmime::types::*; -use mmime::mailmime::*; -use mmime::other::*; - -use crate::blob::BlobObject; -use crate::constants::Viewtype; -use crate::contact::*; -use crate::context::Context; -use crate::dc_simplify::*; -use crate::dc_strencode::*; -use crate::dc_tools::*; -use crate::e2ee; -use crate::error::Error; -use crate::location; -use crate::param::*; -use crate::stock::StockMessage; -use crate::wrapmime; - -#[derive(Debug)] -pub struct MimeParser<'a> { - pub context: &'a Context, - pub parts: Vec, - pub mimeroot: *mut Mailmime, - pub header: HashMap, - pub header_root: *mut mailimf_fields, - pub header_protected: *mut mailimf_fields, - pub subject: Option, - pub is_send_by_messenger: bool, - pub decrypting_failed: bool, - pub encrypted: bool, - pub signatures: HashSet, - pub gossipped_addr: HashSet, - pub is_forwarded: bool, - pub reports: Vec<*mut Mailmime>, - pub is_system_message: SystemMessage, - pub location_kml: Option, - pub message_kml: Option, -} - -#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, ToSql, FromSql)] -#[repr(i32)] -pub enum SystemMessage { - Unknown = 0, - GroupNameChanged = 2, - GroupImageChanged = 3, - MemberAddedToGroup = 4, - MemberRemovedFromGroup = 5, - AutocryptSetupMessage = 6, - SecurejoinMessage = 7, - LocationStreamingEnabled = 8, - LocationOnly = 9, -} - -impl Default for SystemMessage { - fn default() -> Self { - SystemMessage::Unknown - } -} - -const DC_MIMETYPE_MP_ALTERNATIVE: i32 = 10; -const DC_MIMETYPE_MP_RELATED: i32 = 20; -const DC_MIMETYPE_MP_MIXED: i32 = 30; -const DC_MIMETYPE_MP_NOT_DECRYPTABLE: i32 = 40; -const DC_MIMETYPE_MP_REPORT: i32 = 45; -const DC_MIMETYPE_MP_SIGNED: i32 = 46; -const DC_MIMETYPE_MP_OTHER: i32 = 50; -const DC_MIMETYPE_TEXT_PLAIN: i32 = 60; -const DC_MIMETYPE_TEXT_HTML: i32 = 70; -const DC_MIMETYPE_IMAGE: i32 = 80; -const DC_MIMETYPE_AUDIO: i32 = 90; -const DC_MIMETYPE_VIDEO: i32 = 100; -const DC_MIMETYPE_FILE: i32 = 110; -const DC_MIMETYPE_AC_SETUP_FILE: i32 = 111; - -impl<'a> MimeParser<'a> { - pub fn new(context: &'a Context) -> Self { - MimeParser { - parts: Vec::new(), - mimeroot: std::ptr::null_mut(), - header: Default::default(), - header_root: std::ptr::null_mut(), - header_protected: std::ptr::null_mut(), - subject: None, - is_send_by_messenger: false, - decrypting_failed: false, - encrypted: false, - signatures: Default::default(), - gossipped_addr: Default::default(), - is_forwarded: false, - context, - reports: Vec::new(), - is_system_message: SystemMessage::Unknown, - location_kml: None, - message_kml: None, - } - } - - pub unsafe fn parse(&mut self, body: &[u8]) -> Result<(), Error> { - let mut index = 0; - - let r = mailmime_parse( - body.as_ptr() as *const libc::c_char, - body.len(), - &mut index, - &mut self.mimeroot, - ); - - if r == MAILIMF_NO_ERROR as libc::c_int && !self.mimeroot.is_null() { - match e2ee::try_decrypt(self.context, self.mimeroot) { - Ok((encrypted, signatures, gossipped_addr)) => { - self.encrypted = encrypted; - self.signatures = signatures; - self.gossipped_addr = gossipped_addr; - } - Err(err) => { - // continue with the current, still encrypted, mime tree. - // unencrypted parts will be replaced by an error message - // that is added as "the message" to the chat then. - // - // if we just return here, the header is missing - // and the caller cannot display the message - // and try to assign the message to a chat - warn!(self.context, "decryption failed: {}", err); - } - } - - self.parse_mime_recursive(self.mimeroot); - - if let Some(field) = self.lookup_field("Subject") { - if (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int { - let subj = (*(*field).fld_data.fld_subject).sbj_value; - self.subject = to_opt_string_lossy(subj).map(|x| dc_decode_header_words(&x)); - } - } - - if self.lookup_optional_field("Chat-Version").is_some() { - self.is_send_by_messenger = true - } - - if self.lookup_field("Autocrypt-Setup-Message").is_some() { - let has_setup_file = self - .parts - .iter() - .any(|p| p.mimetype == DC_MIMETYPE_AC_SETUP_FILE); - - if has_setup_file { - self.is_system_message = SystemMessage::AutocryptSetupMessage; - - // TODO: replace the following code with this - // once drain_filter stabilizes. - // - // See https://doc.rust-lang.org/std/vec/struct.Vec.html#method.drain_filter - // and https://github.com/rust-lang/rust/issues/43244 - // - // mimeparser - // .parts - // .drain_filter(|part| part.int_mimetype != 111) - // .for_each(|part| dc_mimepart_unref(part)); - - let mut i = 0; - while i != self.parts.len() { - if self.parts[i].mimetype != 111 { - self.parts.remove(i); - } else { - i += 1; - } - } - } - } else if let Some(optional_field) = self.lookup_optional_field("Chat-Content") { - if optional_field == "location-streaming-enabled" { - self.is_system_message = SystemMessage::LocationStreamingEnabled; - } - } - if self.lookup_field("Chat-Group-Image").is_some() && !self.parts.is_empty() { - let textpart = &self.parts[0]; - if textpart.typ == Viewtype::Text && self.parts.len() >= 2 { - let imgpart = &mut self.parts[1]; - if imgpart.typ == Viewtype::Image { - imgpart.is_meta = true; - } - } - } - if self.is_send_by_messenger && self.parts.len() == 2 { - let need_drop = { - let textpart = &self.parts[0]; - let filepart = &self.parts[1]; - textpart.typ == Viewtype::Text - && (filepart.typ == Viewtype::Image - || filepart.typ == Viewtype::Gif - || filepart.typ == Viewtype::Sticker - || filepart.typ == Viewtype::Audio - || filepart.typ == Viewtype::Voice - || filepart.typ == Viewtype::Video - || filepart.typ == Viewtype::File) - && !filepart.is_meta - }; - - if need_drop { - let mut filepart = self.parts.swap_remove(1); - - // insert new one - filepart.msg = self.parts[0].msg.as_ref().map(|s| s.to_string()); - - // forget the one we use now - self.parts[0].msg = None; - - // swap new with old - std::mem::replace(&mut self.parts[0], filepart); - } - } - if let Some(ref subject) = self.subject { - let mut prepend_subject: libc::c_int = 1i32; - if !self.decrypting_failed { - let colon = subject.find(':'); - if colon == Some(2) - || colon == Some(3) - || self.is_send_by_messenger - || subject.contains("Chat:") - { - prepend_subject = 0i32 - } - } - if 0 != prepend_subject { - let subj = if let Some(n) = subject.find('[') { - &subject[0..n] - } else { - subject - } - .trim(); - - if !subj.is_empty() { - for part in self.parts.iter_mut() { - if part.typ == Viewtype::Text { - let new_txt = format!( - "{} – {}", - subj, - part.msg.as_ref().expect("missing msg part") - ); - part.msg = Some(new_txt); - break; - } - } - } - } - } - if self.is_forwarded { - for part in self.parts.iter_mut() { - part.param.set_int(Param::Forwarded, 1); - } - } - if self.parts.len() == 1 { - if self.parts[0].typ == Viewtype::Audio { - if self.lookup_optional_field("Chat-Voice-Message").is_some() { - let part_mut = &mut self.parts[0]; - part_mut.typ = Viewtype::Voice; - } - } - if self.parts[0].typ == Viewtype::Image { - if let Some(content_type) = self.lookup_optional_field("Chat-Content") { - if content_type == "sticker" { - let part_mut = &mut self.parts[0]; - part_mut.typ = Viewtype::Sticker; - } - } - } - let part = &self.parts[0]; - if part.typ == Viewtype::Audio - || part.typ == Viewtype::Voice - || part.typ == Viewtype::Video - { - if let Some(field_0) = self.lookup_optional_field("Chat-Duration") { - let duration_ms = field_0.parse().unwrap_or_default(); - if duration_ms > 0 && duration_ms < 24 * 60 * 60 * 1000 { - let part_mut = &mut self.parts[0]; - part_mut.param.set_int(Param::Duration, duration_ms); - } - } - } - } - if !self.decrypting_failed { - if let Some(dn_field) = - self.lookup_optional_field("Chat-Disposition-Notification-To") - { - if self.get_last_nonmeta().is_some() { - let mut mb_list: *mut mailimf_mailbox_list = ptr::null_mut(); - let mut index_0 = 0; - let dn_field_c = CString::new(dn_field).unwrap_or_default(); - - if mailimf_mailbox_list_parse( - dn_field_c.as_ptr(), - strlen(dn_field_c.as_ptr()), - &mut index_0, - &mut mb_list, - ) == MAILIMF_NO_ERROR as libc::c_int - && !mb_list.is_null() - { - if let Some(dn_to_addr) = wrapmime::mailimf_find_first_addr(mb_list) { - if let Some(from_field) = self.lookup_field("From") { - if (*from_field).fld_type == MAILIMF_FIELD_FROM as libc::c_int - && !(*from_field).fld_data.fld_from.is_null() - { - let from_addr = wrapmime::mailimf_find_first_addr( - (*(*from_field).fld_data.fld_from).frm_mb_list, - ); - if let Some(from_addr) = from_addr { - if from_addr == dn_to_addr { - if let Some(part_4) = self.get_last_nonmeta() { - part_4.param.set_int(Param::WantsMdn, 1); - } - } - } - } - } - } - mailimf_mailbox_list_free(mb_list); - } - } - } - } - } - /* Cleanup - and try to create at least an empty part if there are no parts yet */ - if self.get_last_nonmeta().is_none() && self.reports.is_empty() { - let mut part_5 = Part::default(); - part_5.typ = Viewtype::Text; - part_5.msg = Some("".into()); - - if let Some(ref subject) = self.subject { - if !self.is_send_by_messenger { - part_5.msg = Some(subject.to_string()) - } - } - self.parts.push(part_5); - } - Ok(()) - } - - pub fn get_last_nonmeta(&mut self) -> Option<&mut Part> { - self.parts.iter_mut().rev().find(|part| !part.is_meta) - } - - /* the following functions can be used only after a call to parse() */ - - pub fn lookup_field(&self, field_name: &str) -> Option<*mut mailimf_field> { - match self.header.get(field_name) { - Some(v) => { - if v.is_null() { - None - } else { - Some(*v) - } - } - None => None, - } - } - - pub fn lookup_optional_field(&self, field_name: &str) -> Option { - if let Some(field) = self.lookup_field_typ(field_name, MAILIMF_FIELD_OPTIONAL_FIELD) { - let val = unsafe { (*field).fld_data.fld_optional_field }; - if val.is_null() { - return None; - } else { - return Some(unsafe { to_string_lossy((*val).fld_value) }); - } - } - - None - } - - pub fn lookup_field_typ(&self, name: &str, typ: u32) -> Option<*const mailimf_field> { - if let Some(field) = self.lookup_field(name) { - if unsafe { (*field).fld_type } == typ as libc::c_int { - Some(field) - } else { - None - } - } else { - None - } - } - - unsafe fn parse_mime_recursive(&mut self, mime: *mut Mailmime) -> bool { - if mime.is_null() { - return false; - } - - if !mailmime_find_ct_parameter(mime, "protected-headers").is_null() { - let mime = *mime; - - if mime.mm_type == MAILMIME_SINGLE as libc::c_int - && (*(*mime.mm_content_type).ct_type).tp_type - == MAILMIME_TYPE_DISCRETE_TYPE as libc::c_int - && (*(*(*mime.mm_content_type).ct_type).tp_data.tp_discrete_type).dt_type - == MAILMIME_DISCRETE_TYPE_TEXT as libc::c_int - && !(*mime.mm_content_type).ct_subtype.is_null() - && &to_string_lossy((*mime.mm_content_type).ct_subtype) == "rfc822-headers" - { - info!( - self.context, - "Protected headers found in text/rfc822-headers attachment: Will be ignored.", - ); - return false; - } - - if self.header_protected.is_null() { - /* use the most outer protected header - this is typically - created in sync with the normal, unprotected header */ - let mut dummy = 0; - if mailimf_envelope_and_optional_fields_parse( - mime.mm_mime_start, - mime.mm_length, - &mut dummy, - &mut self.header_protected, - ) != MAILIMF_NO_ERROR as libc::c_int - || self.header_protected.is_null() - { - warn!(self.context, "Protected headers parsing error.",); - } else { - hash_header(&mut self.header, self.header_protected); - } - } else { - info!( - self.context, - "Protected headers found in MIME header: Will be ignored as we already found an outer one." - ); - } - } - - match (*mime).mm_type as u32 { - MAILMIME_SINGLE => self.add_single_part_if_known(mime), - MAILMIME_MULTIPLE => self.handle_multiple(mime), - MAILMIME_MESSAGE => { - if self.header_root.is_null() { - self.header_root = (*mime).mm_data.mm_message.mm_fields; - hash_header(&mut self.header, self.header_root); - } - if (*mime).mm_data.mm_message.mm_msg_mime.is_null() { - return false; - } - - self.parse_mime_recursive((*mime).mm_data.mm_message.mm_msg_mime) - } - _ => false, - } - } - - unsafe fn handle_multiple(&mut self, mime: *mut Mailmime) -> bool { - let mut any_part_added = false; - match mailmime_get_mime_type(mime) { - /* Most times, mutlipart/alternative contains true alternatives - as text/plain and text/html. If we find a multipart/mixed - inside mutlipart/alternative, we use this (happens eg in - apple mail: "plaintext" as an alternative to "html+PDF attachment") */ - (DC_MIMETYPE_MP_ALTERNATIVE, _, _) => { - for cur_data in (*(*mime).mm_data.mm_multipart.mm_mp_list).into_iter() { - if mailmime_get_mime_type(cur_data as *mut _).0 == DC_MIMETYPE_MP_MIXED { - any_part_added = self.parse_mime_recursive(cur_data as *mut _); - break; - } - } - if !any_part_added { - /* search for text/plain and add this */ - for cur_data in (*(*mime).mm_data.mm_multipart.mm_mp_list).into_iter() { - if mailmime_get_mime_type(cur_data as *mut _).0 == DC_MIMETYPE_TEXT_PLAIN { - any_part_added = self.parse_mime_recursive(cur_data as *mut _); - break; - } - } - } - if !any_part_added { - /* `text/plain` not found - use the first part */ - for cur_data in (*(*mime).mm_data.mm_multipart.mm_mp_list).into_iter() { - if self.parse_mime_recursive(cur_data as *mut _) { - any_part_added = true; - break; - } - } - } - } - (DC_MIMETYPE_MP_RELATED, _, _) => { - /* add the "root part" - the other parts may be referenced which is - not interesting for us (eg. embedded images) we assume he "root part" - being the first one, which may not be always true ... - however, most times it seems okay. */ - let cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first; - if !cur.is_null() { - any_part_added = self.parse_mime_recursive((*cur).data as *mut Mailmime); - } - } - (DC_MIMETYPE_MP_NOT_DECRYPTABLE, _, _) => { - let mut part = Part::default(); - part.typ = Viewtype::Text; - let msg_body = self.context.stock_str(StockMessage::CantDecryptMsgBody); - - let txt = format!("[{}]", msg_body); - part.msg_raw = Some(txt.clone()); - part.msg = Some(txt); - - self.parts.push(part); - any_part_added = true; - self.decrypting_failed = true; - } - (DC_MIMETYPE_MP_SIGNED, _, _) => { - /* RFC 1847: "The multipart/signed content type - contains exactly two body parts. The first body - part is the body part over which the digital signature was created [...] - The second body part contains the control information necessary to - verify the digital signature." We simpliy take the first body part and - skip the rest. (see - https://k9mail.github.io/2016/11/24/OpenPGP-Considerations-Part-I.html - for background information why we use encrypted+signed) */ - let cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first; - if !cur.is_null() { - any_part_added = self.parse_mime_recursive((*cur).data as *mut _); - } - } - (DC_MIMETYPE_MP_REPORT, _, _) => { - /* RFC 6522: the first part is for humans, the second for machines */ - if (*(*mime).mm_data.mm_multipart.mm_mp_list).count >= 2 { - let report_type = mailmime_find_ct_parameter(mime, "report-type"); - if !report_type.is_null() - && !(*report_type).pa_value.is_null() - && &to_string_lossy((*report_type).pa_value) == "disposition-notification" - { - self.reports.push(mime); - } else { - /* eg. `report-type=delivery-status`; - maybe we should show them as a little error icon */ - if !(*(*mime).mm_data.mm_multipart.mm_mp_list).first.is_null() { - any_part_added = self.parse_mime_recursive( - (*(*(*mime).mm_data.mm_multipart.mm_mp_list).first).data as *mut _, - ); - } - } - } - } - _ => { - /* eg. DC_MIMETYPE_MP_MIXED - add all parts (in fact, - AddSinglePartIfKnown() later check if the parts are really supported) - HACK: the following lines are a hack for clients who use - multipart/mixed instead of multipart/alternative for - combined text/html messages (eg. Stock Android "Mail" does so). - So, if we detect such a message below, we skip the HTML - part. However, not sure, if there are useful situations to use - plain+html in multipart/mixed - if so, we should disable the hack. */ - let mut skip_part = ptr::null_mut(); - let mut html_part = ptr::null_mut(); - let mut plain_cnt = 0; - let mut html_cnt = 0; - - for cur_data in (*(*mime).mm_data.mm_multipart.mm_mp_list).into_iter() { - match mailmime_get_mime_type(cur_data as *mut _) { - (DC_MIMETYPE_TEXT_PLAIN, _, _) => { - plain_cnt += 1; - } - (DC_MIMETYPE_TEXT_HTML, _, _) => { - html_part = cur_data as *mut Mailmime; - html_cnt += 1; - } - _ => {} - } - } - if plain_cnt == 1 && html_cnt == 1 { - warn!( - self.context, - "HACK: multipart/mixed message found with PLAIN and HTML, we\'ll skip the HTML part as this seems to be unwanted." - ); - skip_part = html_part; - } - - for cur_data in (*(*mime).mm_data.mm_multipart.mm_mp_list).into_iter() { - if cur_data as *mut _ != skip_part { - if self.parse_mime_recursive(cur_data as *mut _) { - any_part_added = true; - } - } - } - } - } - - any_part_added - } - - unsafe fn add_single_part_if_known(&mut self, mime: *mut Mailmime) -> bool { - // return true if a part was added - if mime.is_null() || (*mime).mm_data.mm_single.is_null() { - return false; - } - - let (mime_type, msg_type, raw_mime) = mailmime_get_mime_type(mime); - - let mime_data = (*mime).mm_data.mm_single; - if (*mime_data).dt_type != MAILMIME_DATA_TEXT as libc::c_int - /* MAILMIME_DATA_FILE indicates, the data is in a file; AFAIK this is not used on parsing */ - || (*mime_data).dt_data.dt_text.dt_data.is_null() - || (*mime_data).dt_data.dt_text.dt_length <= 0 - { - return false; - } - - let mut decoded_data = match wrapmime::mailmime_transfer_decode(mime) { - Ok(decoded_data) => decoded_data, - Err(_) => { - // Note that it's not always an error - might be no data - return false; - } - }; - - let old_part_count = self.parts.len(); - - /* regard `Content-Transfer-Encoding:` */ - let mut desired_filename = String::default(); - match mime_type { - DC_MIMETYPE_TEXT_PLAIN | DC_MIMETYPE_TEXT_HTML => { - /* get from `Content-Type: text/...; charset=utf-8`; must not be free()'d */ - let charset = mailmime_content_charset_get((*mime).mm_content_type); - if !charset.is_null() - && strcmp(charset, b"utf-8\x00" as *const u8 as *const libc::c_char) != 0i32 - && strcmp(charset, b"UTF-8\x00" as *const u8 as *const libc::c_char) != 0i32 - { - if let Some(encoding) = - Charset::for_label(CStr::from_ptr(charset).to_string_lossy().as_bytes()) - { - let (res, _, _) = encoding.decode(&decoded_data); - if res.is_empty() { - /* no error - but nothing to add */ - return false; - } - decoded_data = res.as_bytes().to_vec() - } else { - warn!( - self.context, - "Cannot convert {} bytes from \"{}\" to \"utf-8\".", - decoded_data.len(), - to_string_lossy(charset), - ); - } - } - /* check header directly as is_send_by_messenger is not yet set up */ - let is_msgrmsg = self.lookup_optional_field("Chat-Version").is_some(); - - let mut simplifier = Simplify::new(); - let simplified_txt = if decoded_data.is_empty() { - "".into() - } else { - let input = std::string::String::from_utf8_lossy(&decoded_data); - let is_html = mime_type == 70; - - simplifier.simplify(&input, is_html, is_msgrmsg) - }; - if !simplified_txt.is_empty() { - let mut part = Part::default(); - part.typ = Viewtype::Text; - part.mimetype = mime_type; - part.msg = Some(simplified_txt); - part.msg_raw = - Some(std::string::String::from_utf8_lossy(&decoded_data).to_string()); - self.do_add_single_part(part); - } - - if simplifier.is_forwarded { - self.is_forwarded = true; - } - } - DC_MIMETYPE_IMAGE - | DC_MIMETYPE_AUDIO - | DC_MIMETYPE_VIDEO - | DC_MIMETYPE_FILE - | DC_MIMETYPE_AC_SETUP_FILE => { - /* try to get file name from - `Content-Disposition: ... filename*=...` - or `Content-Disposition: ... filename*0*=... filename*1*=... filename*2*=...` - or `Content-Disposition: ... filename=...` */ - let mut filename_parts = String::new(); - - for cur1 in (*(*(*mime).mm_mime_fields).fld_list).into_iter() { - let field = cur1 as *mut mailmime_field; - if !field.is_null() - && (*field).fld_type == MAILMIME_FIELD_DISPOSITION as libc::c_int - && !(*field).fld_data.fld_disposition.is_null() - { - let file_disposition: *mut mailmime_disposition = - (*field).fld_data.fld_disposition; - if !file_disposition.is_null() { - for cur2 in (*(*file_disposition).dsp_parms).into_iter() { - let dsp_param = cur2 as *mut mailmime_disposition_parm; - if !dsp_param.is_null() { - if (*dsp_param).pa_type - == MAILMIME_DISPOSITION_PARM_PARAMETER as libc::c_int - && !(*dsp_param).pa_data.pa_parameter.is_null() - && !(*(*dsp_param).pa_data.pa_parameter).pa_name.is_null() - && strncmp( - (*(*dsp_param).pa_data.pa_parameter).pa_name, - b"filename*\x00" as *const u8 as *const libc::c_char, - 9, - ) == 0i32 - { - // we assume the filename*?* parts are in order, not seen anything else yet - filename_parts += &to_string_lossy( - (*(*dsp_param).pa_data.pa_parameter).pa_value, - ); - } else if (*dsp_param).pa_type - == MAILMIME_DISPOSITION_PARM_FILENAME as libc::c_int - { - // might be a wrongly encoded filename - let s = to_string_lossy((*dsp_param).pa_data.pa_filename); - // this is used only if the parts buffer stays empty - desired_filename = dc_decode_header_words(&s) - } - } - } - } - break; - } - } - if !filename_parts.is_empty() { - desired_filename = dc_decode_ext_header(filename_parts.as_bytes()).into_owned(); - } - if desired_filename.is_empty() { - let param = mailmime_find_ct_parameter(mime, "name"); - if !param.is_null() - && !(*param).pa_value.is_null() - && 0 != *(*param).pa_value.offset(0isize) as libc::c_int - { - // might be a wrongly encoded filename - desired_filename = to_string_lossy((*param).pa_value); - } - } - /* if there is still no filename, guess one */ - if desired_filename.is_empty() { - if !(*mime).mm_content_type.is_null() - && !(*(*mime).mm_content_type).ct_subtype.is_null() - { - desired_filename = format!( - "file.{}", - to_string_lossy((*(*mime).mm_content_type).ct_subtype) - ); - } else { - return false; - } - } - self.do_add_single_file_part( - msg_type, - mime_type, - raw_mime.as_ref(), - &decoded_data, - &desired_filename, - ); - } - _ => {} - } - /* add object? (we do not add all objects, eg. signatures etc. are ignored) */ - self.parts.len() > old_part_count - } - - unsafe fn do_add_single_file_part( - &mut self, - msg_type: Viewtype, - mime_type: libc::c_int, - raw_mime: Option<&String>, - decoded_data: &[u8], - filename: &str, - ) { - if decoded_data.is_empty() { - return; - } - // treat location/message kml file attachments specially - if filename.ends_with(".kml") { - // XXX what if somebody sends eg an "location-highlights.kml" - // attachment unrelated to location streaming? - if filename.starts_with("location") || filename.starts_with("message") { - let parsed = location::Kml::parse(self.context, decoded_data) - .map_err(|err| { - warn!(self.context, "failed to parse kml part: {}", err); - }) - .ok(); - if filename.starts_with("location") { - self.location_kml = parsed; - } else { - self.message_kml = parsed; - } - return; - } - } - /* we have a regular file attachment, - write decoded data to new blob object */ - - let blob = match BlobObject::create(self.context, filename, decoded_data) { - Ok(blob) => blob, - Err(err) => { - error!( - self.context, - "Could not add blob for mime part {}, error {}", filename, err - ); - return; - } - }; - - /* create and register Mime part referencing the new Blob object */ - let mut part = Part::default(); - part.typ = msg_type; - part.mimetype = mime_type; - part.bytes = decoded_data.len() as libc::c_int; - part.param.set(Param::File, blob.as_name()); - if let Some(raw_mime) = raw_mime { - part.param.set(Param::MimeType, raw_mime); - } - - if mime_type == DC_MIMETYPE_IMAGE { - if let Ok((width, height)) = dc_get_filemeta(decoded_data) { - part.param.set_int(Param::Width, width as i32); - part.param.set_int(Param::Height, height as i32); - } - } - self.do_add_single_part(part); - } - - fn do_add_single_part(&mut self, mut part: Part) { - if self.encrypted { - if self.signatures.len() > 0 { - part.param.set_int(Param::GuaranteeE2ee, 1); - } else { - // XXX if the message was encrypted but not signed - // it's not neccessarily an error we need to signal. - // we could just treat it as if it was not encrypted. - part.param.set_int(Param::ErroneousE2ee, 0x2); - } - } - self.parts.push(part); - } - - pub fn is_mailinglist_message(&self) -> bool { - if self.lookup_field("List-Id").is_some() { - return true; - } - - if let Some(precedence) = self.lookup_optional_field("Precedence") { - if precedence == "list" || precedence == "bulk" { - return true; - } - } - - false - } - - pub unsafe fn sender_equals_recipient(&self) -> bool { - if self.header_root.is_null() { - return false; - } - - let mut sender_equals_recipient = false; - let mut fld_from: *const mailimf_from = ptr::null(); - - /* get From: and check there is exactly one sender */ - let fld = wrapmime::mailimf_find_field(self.header_root, MAILIMF_FIELD_FROM as libc::c_int); - if !(fld.is_null() - || { - fld_from = (*fld).fld_data.fld_from; - fld_from.is_null() - } - || (*fld_from).frm_mb_list.is_null() - || (*(*fld_from).frm_mb_list).mb_list.is_null() - || (*(*(*fld_from).frm_mb_list).mb_list).count != 1i32) - { - let mb = (if !(*(*(*fld_from).frm_mb_list).mb_list).first.is_null() { - (*(*(*(*fld_from).frm_mb_list).mb_list).first).data - } else { - ptr::null_mut() - }) as *mut mailimf_mailbox; - - if !mb.is_null() { - let from_addr = to_string_lossy((*mb).mb_addr_spec); - let from_addr_norm = addr_normalize(&from_addr); - let recipients = wrapmime::mailimf_get_recipients(self.header_root); - if recipients.len() == 1 && recipients.contains(from_addr_norm) { - sender_equals_recipient = true; - } - } - } - - sender_equals_recipient - } - - pub fn repl_msg_by_error(&mut self, error_msg: impl AsRef) { - if self.parts.is_empty() { - return; - } - - let part = &mut self.parts[0]; - part.typ = Viewtype::Text; - part.msg = Some(format!("[{}]", error_msg.as_ref())); - self.parts.truncate(1); - - assert_eq!(self.parts.len(), 1); - } - - pub fn get_rfc724_mid(&mut self) -> Option { - // get Message-ID from header - if let Some(field) = self.lookup_field_typ("Message-ID", MAILIMF_FIELD_MESSAGE_ID) { - unsafe { - let fld_message_id = (*field).fld_data.fld_message_id; - if !fld_message_id.is_null() { - return Some(to_string_lossy((*fld_message_id).mid_value)); - } - } - } - None - } -} - -impl<'a> Drop for MimeParser<'a> { - fn drop(&mut self) { - if !self.header_protected.is_null() { - unsafe { mailimf_fields_free(self.header_protected) }; - } - if !self.mimeroot.is_null() { - unsafe { mailmime_free(self.mimeroot) }; - } - } -} - -#[derive(Default, Debug, Clone)] -pub struct Part { - pub typ: Viewtype, - pub is_meta: bool, - pub mimetype: i32, - pub msg: Option, - pub msg_raw: Option, - pub bytes: i32, - pub param: Params, -} - -unsafe fn hash_header(out: &mut HashMap, in_0: *const mailimf_fields) { - if in_0.is_null() { - return; - } - - for cur in (*(*in_0).fld_list).into_iter() { - let field = cur as *mut mailimf_field; - // TODO match on enums /rtn - - let key = match (*field).fld_type as libc::c_uint { - MAILIMF_FIELD_RETURN_PATH => Some("Return-Path".to_string()), - MAILIMF_FIELD_ORIG_DATE => Some("Date".to_string()), - MAILIMF_FIELD_FROM => Some("From".to_string()), - MAILIMF_FIELD_SENDER => Some("Sender".to_string()), - MAILIMF_FIELD_REPLY_TO => Some("Reply-To".to_string()), - MAILIMF_FIELD_TO => Some("To".to_string()), - MAILIMF_FIELD_CC => Some("Cc".to_string()), - MAILIMF_FIELD_BCC => Some("Bcc".to_string()), - MAILIMF_FIELD_MESSAGE_ID => Some("Message-ID".to_string()), - MAILIMF_FIELD_IN_REPLY_TO => Some("In-Reply-To".to_string()), - MAILIMF_FIELD_REFERENCES => Some("References".to_string()), - MAILIMF_FIELD_SUBJECT => Some("Subject".to_string()), - MAILIMF_FIELD_OPTIONAL_FIELD => { - // MAILIMF_FIELD_OPTIONAL_FIELD - let optional_field = (*field).fld_data.fld_optional_field; - // XXX the optional field sometimes contains invalid UTF8 - // which should not happen (according to the mime standard). - // This might point to a bug in our mime parsing/processing - // logic. As mmime/dc_mimeparser is scheduled fore replacement - // anyway we just use a lossy conversion. - - if !optional_field.is_null() { - Some(to_string_lossy((*optional_field).fld_name)) - } else { - None - } - } - _ => None, - }; - if let Some(key) = key { - if !out.contains_key(&key) || // key already exists, only overwrite known types (protected headers) - (*field).fld_type != MAILIMF_FIELD_OPTIONAL_FIELD as i32 || key.starts_with("Chat-") - { - out.insert(key, field); - } - } - } -} - -unsafe fn mailmime_get_mime_type(mime: *mut Mailmime) -> (libc::c_int, Viewtype, Option) { - let c = (*mime).mm_content_type; - - let unknown_type = (0, Viewtype::Unknown, None); - - if c.is_null() || (*c).ct_type.is_null() { - return unknown_type; - } - - match (*(*c).ct_type).tp_type as libc::c_uint { - MAILMIME_TYPE_DISCRETE_TYPE => match (*(*(*c).ct_type).tp_data.tp_discrete_type).dt_type - as libc::c_uint - { - MAILMIME_DISCRETE_TYPE_TEXT => { - if !mailmime_is_attachment_disposition(mime) { - if strcmp( - (*c).ct_subtype, - b"plain\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - return (DC_MIMETYPE_TEXT_PLAIN, Viewtype::Text, None); - } else if strcmp( - (*c).ct_subtype, - b"html\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - return (DC_MIMETYPE_TEXT_HTML, Viewtype::Text, None); - } - } - - let raw_mime = reconcat_mime(Some("text"), to_opt_string_lossy((*c).ct_subtype)); - (DC_MIMETYPE_FILE, Viewtype::File, Some(raw_mime)) - } - MAILMIME_DISCRETE_TYPE_IMAGE => { - let subtype = to_opt_string_lossy((*c).ct_subtype); - let msg_type = match subtype.as_ref().map(|x| x.as_str()) { - Some("gif") => Viewtype::Gif, - Some("svg+xml") => { - let raw_mime = - reconcat_mime(Some("image"), to_opt_string_lossy((*c).ct_subtype)); - return (DC_MIMETYPE_FILE, Viewtype::File, Some(raw_mime)); - } - _ => Viewtype::Image, - }; - - let raw_mime = reconcat_mime(Some("image"), subtype); - (DC_MIMETYPE_IMAGE, msg_type, Some(raw_mime)) - } - MAILMIME_DISCRETE_TYPE_AUDIO => { - let raw_mime = reconcat_mime(Some("audio"), to_opt_string_lossy((*c).ct_subtype)); - (DC_MIMETYPE_AUDIO, Viewtype::Audio, Some(raw_mime)) - } - MAILMIME_DISCRETE_TYPE_VIDEO => { - let raw_mime = reconcat_mime(Some("video"), to_opt_string_lossy((*c).ct_subtype)); - (DC_MIMETYPE_VIDEO, Viewtype::Video, Some(raw_mime)) - } - _ => { - if (*(*(*c).ct_type).tp_data.tp_discrete_type).dt_type - == MAILMIME_DISCRETE_TYPE_APPLICATION as libc::c_int - && strcmp( - (*c).ct_subtype, - b"autocrypt-setup\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { - let raw_mime = reconcat_mime(None, to_opt_string_lossy((*c).ct_subtype)); - return (DC_MIMETYPE_AC_SETUP_FILE, Viewtype::File, Some(raw_mime)); - } - - let raw_mime = reconcat_mime( - to_opt_string_lossy((*(*(*c).ct_type).tp_data.tp_discrete_type).dt_extension) - .as_ref() - .map(|x| x.as_str()), - to_opt_string_lossy((*c).ct_subtype), - ); - - (DC_MIMETYPE_FILE, Viewtype::File, Some(raw_mime)) - } - }, - MAILMIME_TYPE_COMPOSITE_TYPE => { - if (*(*(*c).ct_type).tp_data.tp_composite_type).ct_type - == MAILMIME_COMPOSITE_TYPE_MULTIPART as libc::c_int - { - let subtype = to_opt_string_lossy((*c).ct_subtype); - - let mime_type = match subtype.as_ref().map(|x| x.as_str()) { - Some("alternative") => DC_MIMETYPE_MP_ALTERNATIVE, - Some("related") => DC_MIMETYPE_MP_RELATED, - Some("encrypted") => { - // maybe try_decrypt failed to decrypt - // or it wasn't in proper Autocrypt format - DC_MIMETYPE_MP_NOT_DECRYPTABLE - } - Some("signed") => DC_MIMETYPE_MP_SIGNED, - Some("mixed") => DC_MIMETYPE_MP_MIXED, - Some("report") => DC_MIMETYPE_MP_REPORT, - _ => DC_MIMETYPE_MP_OTHER, - }; - - (mime_type, Viewtype::Unknown, None) - } else { - if (*(*(*c).ct_type).tp_data.tp_composite_type).ct_type - == MAILMIME_COMPOSITE_TYPE_MESSAGE as libc::c_int - { - // Enacapsulated messages, see https://www.w3.org/Protocols/rfc1341/7_3_Message.html - // Also used as part "message/disposition-notification" of "multipart/report", which, however, will - // be handled separatedly. - // I've not seen any messages using this, so we do not attach these parts (maybe they're used to attach replies, - // which are unwanted at all). - // For now, we skip these parts at all; if desired, we could return DC_MIMETYPE_FILE/DC_MSG_FILE - // for selected and known subparts. - } - - unknown_type - } - } - _ => unknown_type, - } -} - -fn reconcat_mime(typ: Option<&str>, subtype: Option) -> String { - let typ = typ.unwrap_or("application"); - let subtype = subtype.unwrap_or("octet-stream".to_string()); - - format!("{}/{}", typ, subtype) -} - -unsafe fn mailmime_is_attachment_disposition(mime: *mut Mailmime) -> bool { - if (*mime).mm_mime_fields.is_null() { - return false; - } - - for cur in (*(*(*mime).mm_mime_fields).fld_list).into_iter() { - let field = cur as *mut mailmime_field; - if !field.is_null() - && (*field).fld_type == MAILMIME_FIELD_DISPOSITION as libc::c_int - && !(*field).fld_data.fld_disposition.is_null() - { - if !(*(*field).fld_data.fld_disposition).dsp_type.is_null() - && (*(*(*field).fld_data.fld_disposition).dsp_type).dsp_type - == MAILMIME_DISPOSITION_TYPE_ATTACHMENT as libc::c_int - { - return true; - } - } - } - - false -} - -/* low-level-tools for working with mailmime structures directly */ -pub unsafe fn mailmime_find_ct_parameter( - mime: *mut Mailmime, - name: &str, -) -> *mut mailmime_parameter { - if mime.is_null() - || (*mime).mm_content_type.is_null() - || (*(*mime).mm_content_type).ct_parameters.is_null() - { - return ptr::null_mut(); - } - - for cur in (*(*(*mime).mm_content_type).ct_parameters).into_iter() { - let param = cur as *mut mailmime_parameter; - if !param.is_null() && !(*param).pa_name.is_null() { - if &to_string_lossy((*param).pa_name) == name { - return param; - } - } - } - - ptr::null_mut() -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::test_utils::*; - use proptest::prelude::*; - use std::ffi::CStr; - - #[test] - fn test_mailmime_parse() { - unsafe { - let txt: *const libc::c_char = - b"FieldA: ValueA\nFieldB: ValueB\n\x00" as *const u8 as *const libc::c_char; - let mut mime: *mut Mailmime = ptr::null_mut(); - let mut dummy = 0; - let res = mailmime_parse(txt, strlen(txt), &mut dummy, &mut mime); - assert_eq!(res, MAIL_NO_ERROR as libc::c_int); - assert!(!mime.is_null()); - - let fields: *mut mailimf_fields = wrapmime::mailmime_find_mailimf_fields(mime); - assert!(!fields.is_null()); - - let mut of_a: *mut mailimf_optional_field = wrapmime::mailimf_find_optional_field( - fields, - b"fielda\x00" as *const u8 as *const libc::c_char, - ); - - assert!(!of_a.is_null()); - assert!(!(*of_a).fld_value.is_null()); - assert_eq!( - CStr::from_ptr((*of_a).fld_name as *const libc::c_char) - .to_str() - .unwrap(), - "FieldA", - ); - assert_eq!( - CStr::from_ptr((*of_a).fld_value as *const libc::c_char) - .to_str() - .unwrap(), - "ValueA", - ); - - of_a = wrapmime::mailimf_find_optional_field( - fields, - b"FIELDA\x00" as *const u8 as *const libc::c_char, - ); - - assert!(!of_a.is_null()); - assert!(!(*of_a).fld_value.is_null()); - assert_eq!( - CStr::from_ptr((*of_a).fld_name as *const libc::c_char) - .to_str() - .unwrap(), - "FieldA", - ); - assert_eq!( - CStr::from_ptr((*of_a).fld_value as *const libc::c_char) - .to_str() - .unwrap(), - "ValueA", - ); - - let of_b: *mut mailimf_optional_field = wrapmime::mailimf_find_optional_field( - fields, - b"FieldB\x00" as *const u8 as *const libc::c_char, - ); - - assert!(!of_b.is_null()); - assert!(!(*of_b).fld_value.is_null()); - assert_eq!( - CStr::from_ptr((*of_b).fld_value as *const libc::c_char) - .to_str() - .unwrap(), - "ValueB", - ); - - mailmime_free(mime); - } - } - - #[test] - fn test_dc_mimeparser_crash() { - let context = dummy_context(); - let raw = include_bytes!("../test-data/message/issue_523.txt"); - let mut mimeparser = MimeParser::new(&context.ctx); - unsafe { - mimeparser.parse(&raw[..]).unwrap(); - }; - assert_eq!(mimeparser.subject, None); - assert_eq!(mimeparser.parts.len(), 1); - } - - proptest! { - #[ignore] - #[test] - fn test_dc_mailmime_parse_crash_fuzzy(data in "[!-~\t ]{2000,}") { - let context = dummy_context(); - let mut mimeparser = MimeParser::new(&context.ctx); - - // parsing should always succeed - // but the returned header will normally be empty on random data - assert!(unsafe {mimeparser.parse(data.as_bytes()).is_ok()}); - assert!(mimeparser.header.is_empty()); - } - } - - #[test] - fn test_get_rfc724_mid_exists() { - let context = dummy_context(); - let raw = include_bytes!("../test-data/message/mail_with_message_id.txt"); - let mut mimeparser = MimeParser::new(&context.ctx); - unsafe { mimeparser.parse(&raw[..]).unwrap() }; - assert_eq!( - mimeparser.get_rfc724_mid(), - Some("2dfdbde7@example.org".into()) - ); - } - - #[test] - fn test_get_rfc724_mid_not_exists() { - let context = dummy_context(); - let raw = include_bytes!("../test-data/message/issue_523.txt"); - let mut mimeparser = MimeParser::new(&context.ctx); - unsafe { mimeparser.parse(&raw[..]).unwrap() }; - assert_eq!(mimeparser.get_rfc724_mid(), None); - } - - #[test] - fn test_mimeparser_with_context() { - unsafe { - let context = dummy_context(); - let raw = b"From: hello\nContent-Type: multipart/mixed; boundary=\"==break==\";\nSubject: outer-subject\nX-Special-A: special-a\nFoo: Bar\nChat-Version: 0.0\n\n--==break==\nContent-Type: text/plain; protected-headers=\"v1\";\nSubject: inner-subject\nX-Special-B: special-b\nFoo: Xy\nChat-Version: 1.0\n\ntest1\n\n--==break==--\n\n\x00"; - let mut mimeparser = MimeParser::new(&context.ctx); - mimeparser.parse(&raw[..]).unwrap(); - - assert_eq!(mimeparser.subject, Some("inner-subject".into())); - - let of = mimeparser.lookup_optional_field("X-Special-A").unwrap(); - assert_eq!(&of, "special-a"); - - let of = mimeparser.lookup_optional_field("Foo").unwrap(); - assert_eq!(&of, "Bar"); - - let of = mimeparser.lookup_optional_field("Chat-Version").unwrap(); - assert_eq!(&of, "1.0"); - assert_eq!(mimeparser.parts.len(), 1); - } - } -} diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 466698dac..ad559bb57 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -1,13 +1,4 @@ -use std::ptr; - use itertools::join; -use libc::strcmp; -use mmime::clist::*; -use mmime::mailimf::types::*; -use mmime::mailmime::content::*; -use mmime::mailmime::types::*; -use mmime::mailmime::*; -use mmime::other::*; use sha2::{Digest, Sha256}; use num_traits::FromPrimitive; @@ -18,20 +9,18 @@ use crate::config::Config; use crate::constants::*; use crate::contact::*; use crate::context::Context; -use crate::dc_mimeparser::*; -use crate::dc_strencode::*; use crate::dc_tools::*; use crate::error::Result; use crate::events::Event; use crate::job::*; use crate::location; use crate::message::{self, MessageState, MsgId}; +use crate::mimeparser::*; use crate::param::*; use crate::peerstate::*; use crate::securejoin::handle_securejoin_handshake; use crate::sql; use crate::stock::StockMessage; -use crate::wrapmime; #[derive(Debug, PartialEq, Eq)] enum CreateEvent { @@ -40,7 +29,7 @@ enum CreateEvent { } /// Receive a message and add it to the database. -pub unsafe fn dc_receive_imf( +pub fn dc_receive_imf( context: &Context, imf_raw: &[u8], server_folder: impl AsRef, @@ -63,9 +52,12 @@ pub unsafe fn dc_receive_imf( // we use mailmime_parse() through dc_mimeparser (both call mailimf_struct_multiple_parse() // somewhen, I did not found out anything that speaks against this approach yet) - let mut mime_parser = MimeParser::new(context); - if let Err(err) = mime_parser.parse(imf_raw) { + let mime_parser = MimeParser::from_bytes(context, imf_raw); + let mut mime_parser = if let Err(err) = mime_parser { warn!(context, "dc_receive_imf parse error: {}", err); + return; + } else { + mime_parser.unwrap() }; if mime_parser.header.is_empty() { @@ -77,7 +69,7 @@ pub unsafe fn dc_receive_imf( // the function returns the number of created messages in the database let mut incoming = 1; let mut incoming_origin = Origin::Unknown; - let mut to_self = 0; + let mut to_self = false; let mut from_id = 0u32; let mut from_id_blocked = 0; let mut to_id = 0u32; @@ -122,62 +114,53 @@ pub unsafe fn dc_receive_imf( } }; - if let Some(field) = mime_parser.lookup_field_typ("Date", MAILIMF_FIELD_ORIG_DATE) { - let orig_date = (*field).fld_data.fld_orig_date; - if !orig_date.is_null() { - // is not yet checked against bad times! we do this later if we have the database information. - sent_timestamp = dc_timestamp_from_date((*orig_date).dt_date_time) - } + if let Some(value) = mime_parser.lookup_field("Date") { + // is not yet checked against bad times! we do this later if we have the database information. + sent_timestamp = mailparse::dateparse(value).unwrap_or_default(); } // get From: and check if it is known (for known From:'s we add the other To:/Cc: in the 3rd pass) // or if From: is equal to SELF (in this case, it is any outgoing messages, // we do not check Return-Path any more as this is unreliable, see issue #150 - if let Some(field) = mime_parser.lookup_field_typ("From", MAILIMF_FIELD_FROM) { - let fld_from = (*field).fld_data.fld_from; - if !fld_from.is_null() { - let mut check_self = 0; - let mut from_list = Vec::with_capacity(16); - dc_add_or_lookup_contacts_by_mailbox_list( - context, - (*fld_from).frm_mb_list, - Origin::IncomingUnknownFrom, - &mut from_list, - &mut check_self, - ); - if 0 != check_self { - incoming = 0; - if mime_parser.sender_equals_recipient() { - from_id = DC_CONTACT_ID_SELF; - } - } else if !from_list.is_empty() { - // if there is no from given, from_id stays 0 which is just fine. These messages - // are very rare, however, we have to add them to the database (they go to the - // "deaddrop" chat) to avoid a re-download from the server. See also [**] - from_id = from_list[0]; - incoming_origin = Contact::get_origin_by_id(context, from_id, &mut from_id_blocked) + if let Some(field_from) = mime_parser.lookup_field("From") { + let mut check_self = false; + let mut from_list = Vec::with_capacity(16); + dc_add_or_lookup_contacts_by_address_list( + context, + &field_from, + Origin::IncomingUnknownFrom, + &mut from_list, + &mut check_self, + ); + if check_self { + incoming = 0; + if mime_parser.sender_equals_recipient() { + from_id = DC_CONTACT_ID_SELF; } + } else if !from_list.is_empty() { + // if there is no from given, from_id stays 0 which is just fine. These messages + // are very rare, however, we have to add them to the database (they go to the + // "deaddrop" chat) to avoid a re-download from the server. See also [**] + from_id = from_list[0]; + incoming_origin = Contact::get_origin_by_id(context, from_id, &mut from_id_blocked) } } // Make sure, to_ids starts with the first To:-address (Cc: is added in the loop below pass) - if let Some(field) = mime_parser.lookup_field_typ("To", MAILIMF_FIELD_TO) { - let fld_to = (*field).fld_data.fld_to; - if !fld_to.is_null() { - dc_add_or_lookup_contacts_by_address_list( - context, - (*fld_to).to_addr_list, - if 0 == incoming { - Origin::OutgoingTo - } else if incoming_origin.is_verified() { - Origin::IncomingTo - } else { - Origin::IncomingUnknownTo - }, - &mut to_ids, - &mut to_self, - ); - } + if let Some(field) = mime_parser.lookup_field("To") { + dc_add_or_lookup_contacts_by_address_list( + context, + &field, + if 0 == incoming { + Origin::OutgoingTo + } else if incoming_origin.is_verified() { + Origin::IncomingTo + } else { + Origin::IncomingUnknownTo + }, + &mut to_ids, + &mut to_self, + ); } // Add parts @@ -245,17 +228,13 @@ pub unsafe fn dc_receive_imf( } } - if !mime_parser.reports.is_empty() { - handle_reports( - context, - &mime_parser, - from_id, - sent_timestamp, - &mut rr_event_to_send, - &server_folder, - server_uid, - ); - } + mime_parser.handle_reports( + from_id, + sent_timestamp, + &mut rr_event_to_send, + &server_folder, + server_uid, + ); if mime_parser.location_kml.is_some() || mime_parser.message_kml.is_some() { save_locations( @@ -294,7 +273,7 @@ pub unsafe fn dc_receive_imf( ); } -unsafe fn add_parts( +fn add_parts( context: &Context, mut mime_parser: &mut MimeParser, imf_raw: &[u8], @@ -307,18 +286,18 @@ unsafe fn add_parts( sent_timestamp: &mut i64, from_id: &mut u32, from_id_blocked: i32, - hidden: &mut libc::c_int, + hidden: &mut i32, chat_id: &mut u32, to_id: &mut u32, flags: u32, needs_delete_job: &mut bool, - to_self: i32, + to_self: bool, insert_msg_id: &mut MsgId, created_db_entries: &mut Vec<(usize, MsgId)>, create_event_to_send: &mut Option, ) -> Result<()> { let mut state: MessageState; - let mut msgrmsg: libc::c_int; + let mut msgrmsg: i32; let mut chat_id_blocked = Blocked::Not; let mut sort_timestamp = 0; let mut rcvd_timestamp = 0; @@ -328,23 +307,20 @@ unsafe fn add_parts( // collect the rest information, CC: is added to the to-list, BCC: is ignored // (we should not add BCC to groups as this would split groups. We could add them as "known contacts", // however, the benefit is very small and this may leak data that is expected to be hidden) - if let Some(field) = mime_parser.lookup_field_typ("Cc", MAILIMF_FIELD_CC) { - let fld_cc = (*field).fld_data.fld_cc; - if !fld_cc.is_null() { - dc_add_or_lookup_contacts_by_address_list( - context, - (*fld_cc).cc_addr_list, - if 0 == incoming { - Origin::OutgoingCc - } else if incoming_origin.is_verified() { - Origin::IncomingCc - } else { - Origin::IncomingUnknownCc - }, - to_ids, - std::ptr::null_mut(), - ); - } + if let Some(fld_cc) = mime_parser.lookup_field("Cc") { + dc_add_or_lookup_contacts_by_address_list( + context, + fld_cc, + if 0 == incoming { + Origin::OutgoingCc + } else if incoming_origin.is_verified() { + Origin::IncomingCc + } else { + Origin::IncomingUnknownCc + }, + to_ids, + &mut false, + ); } // check, if the mail is already in our database - if so, just update the folder/uid @@ -570,7 +546,7 @@ unsafe fn add_parts( } } if *chat_id == 0 { - if to_ids.is_empty() && 0 != to_self { + if to_ids.is_empty() && to_self { // from_id==to_id==DC_CONTACT_ID_SELF - this is a self-sent messages, // maybe an Autocrypt Setup Messag let (id, bl) = @@ -608,18 +584,12 @@ unsafe fn add_parts( // if the mime-headers should be saved, find out its size // (the mime-header ends with an empty line) let save_mime_headers = context.get_config_bool(Config::SaveMimeHeaders); - if let Some(field) = mime_parser.lookup_field_typ("In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO) { - let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; - if !fld_in_reply_to.is_null() { - mime_in_reply_to = dc_str_from_clist((*(*field).fld_data.fld_in_reply_to).mid_list, " ") - } + if let Some(raw) = mime_parser.lookup_field("In-Reply-To") { + mime_in_reply_to = raw.clone(); } - if let Some(field) = mime_parser.lookup_field_typ("References", MAILIMF_FIELD_REFERENCES) { - let fld_references = (*field).fld_data.fld_references; - if !fld_references.is_null() { - mime_references = dc_str_from_clist((*(*field).fld_data.fld_references).mid_list, " ") - } + if let Some(raw) = mime_parser.lookup_field("References") { + mime_references = raw.clone(); } // fine, so far. now, split the message into simple parts usable as "short messages" @@ -643,17 +613,16 @@ unsafe fn add_parts( continue; } - if let Some(ref msg) = part.msg { - if mime_parser.location_kml.is_some() - && icnt == 1 - && (msg == "-location-" || msg.is_empty()) - { - *hidden = 1; - if state == MessageState::InFresh { - state = MessageState::InNoticed; - } + if mime_parser.location_kml.is_some() + && icnt == 1 + && (part.msg == "-location-" || part.msg.is_empty()) + { + *hidden = 1; + if state == MessageState::InFresh { + state = MessageState::InNoticed; } } + if part.typ == Viewtype::Text { let msg_raw = part.msg_raw.as_ref().cloned().unwrap_or_default(); let subject = mime_parser @@ -671,21 +640,21 @@ unsafe fn add_parts( stmt.execute(params![ rfc724_mid, server_folder.as_ref(), - server_uid as libc::c_int, - *chat_id as libc::c_int, - *from_id as libc::c_int, - *to_id as libc::c_int, + server_uid as i32, + *chat_id as i32, + *from_id as i32, + *to_id as i32, sort_timestamp, *sent_timestamp, rcvd_timestamp, part.typ, state, msgrmsg, - part.msg.as_ref().map_or("", String::as_str), + &part.msg, // txt_raw might contain invalid utf8 txt_raw.unwrap_or_default(), part.param.to_string(), - part.bytes, + part.bytes as isize, *hidden, if save_mime_headers { Some(String::from_utf8_lossy(imf_raw)) @@ -727,137 +696,6 @@ unsafe fn add_parts( Ok(()) } -// Handle reports (mainly MDNs) -unsafe fn handle_reports( - context: &Context, - mime_parser: &MimeParser, - from_id: u32, - sent_timestamp: i64, - rr_event_to_send: &mut Vec<(u32, MsgId)>, - server_folder: impl AsRef, - server_uid: u32, -) { - let mdns_enabled = context.get_config_bool(Config::MdnsEnabled); - - for report_root in &mime_parser.reports { - let report_root = *report_root; - let mut mdn_consumed = 0; - let report_type = mailmime_find_ct_parameter(report_root, "report-type"); - - if report_root.is_null() || report_type.is_null() || (*report_type).pa_value.is_null() { - continue; - } - - // the first part is for humans, the second for machines - if strcmp( - (*report_type).pa_value, - b"disposition-notification\x00" as *const u8 as *const libc::c_char, - ) == 0 - && (*(*report_root).mm_data.mm_multipart.mm_mp_list).count >= 2 - { - // to get a clear functionality, do not show incoming MDNs if the options is disabled - if mdns_enabled { - let report_data = (if !if !(*(*report_root).mm_data.mm_multipart.mm_mp_list) - .first - .is_null() - { - (*(*(*report_root).mm_data.mm_multipart.mm_mp_list).first).next - } else { - ptr::null_mut() - } - .is_null() - { - (*if !(*(*report_root).mm_data.mm_multipart.mm_mp_list) - .first - .is_null() - { - (*(*(*report_root).mm_data.mm_multipart.mm_mp_list).first).next - } else { - ptr::null_mut() - }) - .data - } else { - ptr::null_mut() - }) as *mut Mailmime; - - if !report_data.is_null() - && (*(*(*report_data).mm_content_type).ct_type).tp_type - == MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int - && (*(*(*(*report_data).mm_content_type).ct_type) - .tp_data - .tp_composite_type) - .ct_type - == MAILMIME_COMPOSITE_TYPE_MESSAGE as libc::c_int - && strcmp( - (*(*report_data).mm_content_type).ct_subtype, - b"disposition-notification\x00" as *const u8 as *const libc::c_char, - ) == 0 - { - if let Ok(report_body) = wrapmime::mailmime_transfer_decode(report_data) { - let mut report_parsed = std::ptr::null_mut(); - let mut dummy = 0; - - if mailmime_parse( - report_body.as_ptr() as *const _, - report_body.len(), - &mut dummy, - &mut report_parsed, - ) == MAIL_NO_ERROR as libc::c_int - && !report_parsed.is_null() - { - let report_fields = - wrapmime::mailmime_find_mailimf_fields(report_parsed); - if !report_fields.is_null() { - let of_disposition = wrapmime::mailimf_find_optional_field( - report_fields, - b"Disposition\x00" as *const u8 as *const libc::c_char, - ); - let of_org_msgid = wrapmime::mailimf_find_optional_field( - report_fields, - b"Original-Message-ID\x00" as *const u8 as *const libc::c_char, - ); - if !of_disposition.is_null() - && !(*of_disposition).fld_value.is_null() - && !of_org_msgid.is_null() - && !(*of_org_msgid).fld_value.is_null() - { - if let Ok(rfc724_mid) = - wrapmime::parse_message_id(std::slice::from_raw_parts( - (*of_org_msgid).fld_value as *const u8, - libc::strlen((*of_org_msgid).fld_value), - )) - { - if let Some((chat_id, msg_id)) = message::mdn_from_ext( - context, - from_id, - &rfc724_mid, - sent_timestamp, - ) { - rr_event_to_send.push((chat_id, msg_id)); - mdn_consumed = 1; - } - } - } - } - mailmime_free(report_parsed); - } - } - } - } - - if mime_parser.is_send_by_messenger || 0 != mdn_consumed { - let mut param = Params::new(); - param.set(Param::ServerFolder, server_folder.as_ref()); - param.set_int(Param::ServerUid, server_uid as i32); - if mime_parser.is_send_by_messenger && context.get_config_bool(Config::MvboxMove) { - param.set_int(Param::AlsoMove, 1); - } - job_add(context, Action::MarkseenMdnOnImap, 0, param, 0); - } - } - } -} - fn save_locations( context: &Context, mime_parser: &MimeParser, @@ -911,15 +749,15 @@ fn save_locations( } } -unsafe fn calc_timestamps( +fn calc_timestamps( context: &Context, chat_id: u32, from_id: u32, message_timestamp: i64, - is_fresh_msg: libc::c_int, - sort_timestamp: *mut i64, - sent_timestamp: *mut i64, - rcvd_timestamp: *mut i64, + is_fresh_msg: i32, + sort_timestamp: &mut i64, + sent_timestamp: &mut i64, + rcvd_timestamp: &mut i64, ) { *rcvd_timestamp = time(); *sent_timestamp = message_timestamp; @@ -958,10 +796,10 @@ unsafe fn calc_timestamps( /// /// So when the function returns, the caller has the group id matching the current state of the group. #[allow(non_snake_case)] -unsafe fn create_or_lookup_group( +fn create_or_lookup_group( context: &Context, mime_parser: &mut MimeParser, - allow_creation: libc::c_int, + allow_creation: i32, create_blocked: Blocked, from_id: u32, to_ids: &mut Vec, @@ -987,7 +825,7 @@ unsafe fn create_or_lookup_group( chat_id: u32, chat_id_blocked: Blocked| { if !ret_chat_id.is_null() { - *ret_chat_id = chat_id; + unsafe { *ret_chat_id = chat_id }; } *ret_chat_id_blocked = if 0 != chat_id { chat_id_blocked @@ -1002,44 +840,25 @@ unsafe fn create_or_lookup_group( } set_better_msg(mime_parser, &better_msg); - if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-ID") { - grpid = optional_field; + if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-ID") { + grpid = optional_field.clone(); } if grpid.is_empty() { - if let Some(field) = mime_parser.lookup_field_typ("Message-ID", MAILIMF_FIELD_MESSAGE_ID) { - let fld_message_id = (*field).fld_data.fld_message_id; - if !fld_message_id.is_null() { - if let Some(extracted_grpid) = - dc_extract_grpid_from_rfc724_mid(&to_string_lossy((*fld_message_id).mid_value)) - { - grpid = extracted_grpid.to_string(); - } else { - grpid = "".to_string(); - } + if let Some(value) = mime_parser.lookup_field("Message-ID") { + if let Some(extracted_grpid) = dc_extract_grpid_from_rfc724_mid(&value) { + grpid = extracted_grpid.to_string(); + } else { + grpid = "".to_string(); } } if grpid.is_empty() { - if let Some(field) = - mime_parser.lookup_field_typ("In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO) - { - let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; - if !fld_in_reply_to.is_null() { - grpid = to_string_lossy(dc_extract_grpid_from_rfc724_mid_list( - (*fld_in_reply_to).mid_list, - )); - } + if let Some(value) = mime_parser.lookup_field("In-Reply-To") { + grpid = value.clone(); } if grpid.is_empty() { - if let Some(field) = - mime_parser.lookup_field_typ("References", MAILIMF_FIELD_REFERENCES) - { - let fld_references = (*field).fld_data.fld_references; - if !fld_references.is_null() { - grpid = to_string_lossy(dc_extract_grpid_from_rfc724_mid_list( - (*fld_references).mid_list, - )); - } + if let Some(value) = mime_parser.lookup_field("References") { + grpid = value.clone(); } if grpid.is_empty() { @@ -1060,14 +879,17 @@ unsafe fn create_or_lookup_group( } } - if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Name") { - grpname = Some(dc_decode_header_words(&optional_field)); + if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-Name").cloned() { + grpname = Some(optional_field); } - if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Member-Removed") { + let field = mime_parser + .lookup_field("Chat-Group-Member-Removed") + .cloned(); + if let Some(optional_field) = field { X_MrRemoveFromGrp = Some(optional_field); mime_parser.is_system_message = SystemMessage::MemberRemovedFromGroup; let left_group = (Contact::lookup_id_by_addr(context, X_MrRemoveFromGrp.as_ref().unwrap()) - == from_id as u32) as libc::c_int; + == from_id as u32) as i32; better_msg = context.stock_system_msg( if 0 != left_group { StockMessage::MsgGroupLeft @@ -1079,10 +901,11 @@ unsafe fn create_or_lookup_group( from_id as u32, ) } else { - if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Member-Added") { + let field = mime_parser.lookup_field("Chat-Group-Member-Added").cloned(); + if let Some(optional_field) = field { X_MrAddToGrp = Some(optional_field); mime_parser.is_system_message = SystemMessage::MemberAddedToGroup; - if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Image") { + if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-Image").cloned() { X_MrGrpImageChanged = optional_field; } better_msg = context.stock_system_msg( @@ -1092,23 +915,23 @@ unsafe fn create_or_lookup_group( from_id as u32, ) } else { - if let Some(optional_field) = - mime_parser.lookup_optional_field("Chat-Group-Name-Changed") - { + let field = mime_parser.lookup_field("Chat-Group-Name-Changed"); + if field.is_some() { X_MrGrpNameChanged = 1; - mime_parser.is_system_message = SystemMessage::GroupNameChanged; better_msg = context.stock_system_msg( StockMessage::MsgGrpName, - &optional_field, + &field.unwrap(), if let Some(ref name) = grpname { name } else { "" }, from_id as u32, - ) + ); + + mime_parser.is_system_message = SystemMessage::GroupNameChanged; } else { - if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Image") + if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-Image").cloned() { // fld_value is a pointer somewhere into mime_parser, must not be freed X_MrGrpImageChanged = optional_field; @@ -1341,10 +1164,10 @@ unsafe fn create_or_lookup_group( } /// Handle groups for received messages -unsafe fn create_or_lookup_adhoc_group( +fn create_or_lookup_adhoc_group( context: &Context, mime_parser: &MimeParser, - allow_creation: libc::c_int, + allow_creation: i32, create_blocked: Blocked, from_id: u32, to_ids: &mut Vec, @@ -1361,7 +1184,7 @@ unsafe fn create_or_lookup_adhoc_group( chat_id: u32, chat_id_blocked: Blocked| { if !ret_chat_id.is_null() { - *ret_chat_id = chat_id; + unsafe { *ret_chat_id = chat_id }; } *ret_chat_id_blocked = chat_id_blocked; }; @@ -1429,7 +1252,7 @@ unsafe fn create_or_lookup_adhoc_group( let grpname = if let Some(subject) = mime_parser.subject.as_ref().filter(|s| !s.is_empty()) { subject.to_string() } else { - context.stock_string_repl_int(StockMessage::Member, member_ids.len() as libc::c_int) + context.stock_string_repl_int(StockMessage::Member, member_ids.len() as i32) }; // create group record @@ -1448,7 +1271,7 @@ unsafe fn create_or_lookup_adhoc_group( context.call_cb(Event::ChatModified(chat_id)); cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked); - return Ok(()); + Ok(()) } fn create_group_record( @@ -1688,54 +1511,40 @@ fn set_better_msg(mime_parser: &mut MimeParser, better_msg: impl AsRef) { if msg.len() > 0 && !mime_parser.parts.is_empty() { let part = &mut mime_parser.parts[0]; if part.typ == Viewtype::Text { - part.msg = Some(msg.to_string()); + part.msg = msg.to_string(); } - }; + } } -unsafe fn dc_is_reply_to_known_message(context: &Context, mime_parser: &MimeParser) -> libc::c_int { +fn dc_is_reply_to_known_message(context: &Context, mime_parser: &MimeParser) -> i32 { /* check if the message is a reply to a known message; the replies are identified by the Message-ID from `In-Reply-To`/`References:` (to support non-Delta-Clients) */ if let Some(field) = mime_parser.lookup_field("In-Reply-To") { - if (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int { - let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; - if !fld_in_reply_to.is_null() { - if is_known_rfc724_mid_in_list( - context, - (*(*field).fld_data.fld_in_reply_to).mid_list, - ) { - return 1; - } - } + if is_known_rfc724_mid_in_list(context, &field) { + return 1; } } if let Some(field) = mime_parser.lookup_field("References") { - if (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int { - let fld_references = (*field).fld_data.fld_references; - if !fld_references.is_null() - && is_known_rfc724_mid_in_list( - context, - (*(*field).fld_data.fld_references).mid_list, - ) - { - return 1; - } + if is_known_rfc724_mid_in_list(context, &field) { + return 1; } } 0 } -unsafe fn is_known_rfc724_mid_in_list(context: &Context, mid_list: *const clist) -> bool { - if mid_list.is_null() { +fn is_known_rfc724_mid_in_list(context: &Context, mid_list: &String) -> bool { + if mid_list.is_empty() { return false; } - for data in &*mid_list { - if is_known_rfc724_mid(context, data.cast()) != 0 { - return true; + if let Ok(ids) = mailparse::addrparse(mid_list.as_str()) { + for id in ids.iter() { + if is_known_rfc724_mid(context, id) { + return true; + } } } @@ -1743,10 +1552,8 @@ unsafe fn is_known_rfc724_mid_in_list(context: &Context, mid_list: *const clist) } /// Check if a message is a reply to a known message (messenger or non-messenger). -fn is_known_rfc724_mid(context: &Context, rfc724_mid: *const libc::c_char) -> libc::c_int { - if rfc724_mid.is_null() { - return 0; - } +fn is_known_rfc724_mid(context: &Context, rfc724_mid: &mailparse::MailAddr) -> bool { + let addr = extract_single_from_addr(rfc724_mid); context .sql .exists( @@ -1754,122 +1561,92 @@ fn is_known_rfc724_mid(context: &Context, rfc724_mid: *const libc::c_char) -> li LEFT JOIN chats c ON m.chat_id=c.id \ WHERE m.rfc724_mid=? \ AND m.chat_id>9 AND c.blocked=0;", - params![to_string_lossy(rfc724_mid)], + params![addr], ) - .unwrap_or_default() as libc::c_int + .unwrap_or_default() } -unsafe fn dc_is_reply_to_messenger_message( - context: &Context, - mime_parser: &MimeParser, -) -> libc::c_int { +fn dc_is_reply_to_messenger_message(context: &Context, mime_parser: &MimeParser) -> i32 { /* function checks, if the message defined by mime_parser references a message send by us from Delta Chat. This is similar to is_reply_to_known_message() but - checks also if any of the referenced IDs are send by a messenger - it is okay, if the referenced messages are moved to trash here - no check for the Chat-* headers (function is only called if it is no messenger message itself) */ - if let Some(field) = mime_parser.lookup_field("In-Reply-To") { - if (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int { - let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; - if !fld_in_reply_to.is_null() { - if 0 != is_msgrmsg_rfc724_mid_in_list( - context, - (*(*field).fld_data.fld_in_reply_to).mid_list, - ) { - return 1; - } - } + if let Some(value) = mime_parser.lookup_field("In-Reply-To") { + if is_msgrmsg_rfc724_mid_in_list(context, &value) { + return 1; } } - if let Some(field) = mime_parser.lookup_field("References") { - if (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int { - let fld_references: *mut mailimf_references = (*field).fld_data.fld_references; - if !fld_references.is_null() { - if 0 != is_msgrmsg_rfc724_mid_in_list( - context, - (*(*field).fld_data.fld_references).mid_list, - ) { - return 1; - } - } + if let Some(value) = mime_parser.lookup_field("References") { + if is_msgrmsg_rfc724_mid_in_list(context, &value) { + return 1; } } 0 } -unsafe fn is_msgrmsg_rfc724_mid_in_list(context: &Context, mid_list: *const clist) -> libc::c_int { - if !mid_list.is_null() { - let mut cur: *mut clistiter = (*mid_list).first; - while !cur.is_null() { - if 0 != is_msgrmsg_rfc724_mid( - context, - &to_string_lossy((*cur).data as *const libc::c_char), - ) { - return 1; - } - cur = if !cur.is_null() { - (*cur).next - } else { - ptr::null_mut() +fn is_msgrmsg_rfc724_mid_in_list(context: &Context, mid_list: &String) -> bool { + if let Ok(ids) = mailparse::addrparse(mid_list.as_str()) { + for id in ids.iter() { + if is_msgrmsg_rfc724_mid(context, id) { + return true; } } } - 0 + false +} + +fn extract_single_from_addr(addr: &mailparse::MailAddr) -> &String { + match addr { + mailparse::MailAddr::Group(infos) => &infos.addrs[0].addr, + mailparse::MailAddr::Single(info) => &info.addr, + } } /// Check if a message is a reply to any messenger message. -fn is_msgrmsg_rfc724_mid(context: &Context, rfc724_mid: &str) -> libc::c_int { - if rfc724_mid.is_empty() { - return 0; - } +fn is_msgrmsg_rfc724_mid(context: &Context, rfc724_mid: &mailparse::MailAddr) -> bool { + let addr = extract_single_from_addr(rfc724_mid); context .sql .exists( "SELECT id FROM msgs WHERE rfc724_mid=? AND msgrmsg!=0 AND chat_id>9;", - params![rfc724_mid], + params![addr], ) - .unwrap_or_default() as libc::c_int + .unwrap_or_default() } -unsafe fn dc_add_or_lookup_contacts_by_address_list( +fn dc_add_or_lookup_contacts_by_address_list( context: &Context, - adr_list: *const mailimf_address_list, + addr_list_raw: &str, origin: Origin, ids: &mut Vec, - check_self: *mut libc::c_int, + check_self: &mut bool, ) { - if adr_list.is_null() { + let addrs = mailparse::addrparse(addr_list_raw); + if addrs.is_err() { return; } - let mut cur: *mut clistiter = (*(*adr_list).ad_list).first; - while !cur.is_null() { - let adr: *mut mailimf_address = (if !cur.is_null() { - (*cur).data - } else { - ptr::null_mut() - }) as *mut mailimf_address; - if !adr.is_null() { - if (*adr).ad_type == MAILIMF_ADDRESS_MAILBOX as libc::c_int { - let mb: *mut mailimf_mailbox = (*adr).ad_data.ad_mailbox; - if !mb.is_null() { + for addr in addrs.unwrap().iter() { + match addr { + mailparse::MailAddr::Single(info) => { + add_or_lookup_contact_by_addr( + context, + &info.display_name, + &info.addr, + origin, + ids, + check_self, + ); + } + mailparse::MailAddr::Group(infos) => { + for info in &infos.addrs { add_or_lookup_contact_by_addr( context, - (*mb).mb_display_name, - (*mb).mb_addr_spec, - origin, - ids, - check_self, - ); - } - } else if (*adr).ad_type == MAILIMF_ADDRESS_GROUP as libc::c_int { - let group: *mut mailimf_group = (*adr).ad_data.ad_group; - if !group.is_null() && !(*group).grp_mb_list.is_null() { - dc_add_or_lookup_contacts_by_mailbox_list( - context, - (*group).grp_mb_list, + &info.display_name, + &info.addr, origin, ids, check_self, @@ -1877,93 +1654,42 @@ unsafe fn dc_add_or_lookup_contacts_by_address_list( } } } - cur = if !cur.is_null() { - (*cur).next - } else { - ptr::null_mut() - } - } -} - -unsafe fn dc_add_or_lookup_contacts_by_mailbox_list( - context: &Context, - mb_list: *const mailimf_mailbox_list, - origin: Origin, - ids: &mut Vec, - check_self: *mut libc::c_int, -) { - if mb_list.is_null() { - return; - } - let mut cur: *mut clistiter = (*(*mb_list).mb_list).first; - while !cur.is_null() { - let mb: *mut mailimf_mailbox = (if !cur.is_null() { - (*cur).data - } else { - ptr::null_mut() - }) as *mut mailimf_mailbox; - if !mb.is_null() { - add_or_lookup_contact_by_addr( - context, - (*mb).mb_display_name, - (*mb).mb_addr_spec, - origin, - ids, - check_self, - ); - } - cur = if !cur.is_null() { - (*cur).next - } else { - ptr::null_mut() - } } } /// Add contacts to database on receiving messages. -unsafe fn add_or_lookup_contact_by_addr( +fn add_or_lookup_contact_by_addr( context: &Context, - display_name_enc: *const libc::c_char, - addr_spec: *const libc::c_char, + display_name: &Option, + addr: &String, origin: Origin, ids: &mut Vec, - mut check_self: *mut libc::c_int, + check_self: &mut bool, ) { - /* is addr_spec equal to SELF? */ - let mut dummy: libc::c_int = 0; - if check_self.is_null() { - check_self = &mut dummy - } - if addr_spec.is_null() { - return; - } - *check_self = 0; + // is addr_spec equal to SELF? let self_addr = context .get_config(Config::ConfiguredAddr) .unwrap_or_default(); - if addr_cmp(self_addr, to_string_lossy(addr_spec)) { - *check_self = 1; + if addr_cmp(self_addr, addr) { + *check_self = true; } - if 0 != *check_self { + if *check_self { return; } - /* add addr_spec if missing, update otherwise */ - let mut display_name_dec = "".to_string(); - if !display_name_enc.is_null() { - let tmp = dc_decode_header_words(&to_string_lossy(display_name_enc)); - display_name_dec = normalize_name(&tmp); - } - /*can be NULL*/ - let row_id = Contact::add_or_lookup( - context, - display_name_dec, - to_string_lossy(addr_spec), - origin, - ) - .map(|(id, _)| id) - .unwrap_or_default(); + + // add addr_spec if missing, update otherwise + let display_name_normalized = display_name + .as_ref() + .map(normalize_name) + .unwrap_or_default(); + + // can be NULL + let row_id = Contact::add_or_lookup(context, display_name_normalized, addr, origin) + .map(|(id, _)| id) + .unwrap_or_default(); + if 0 != row_id && !ids.contains(&row_id) { ids.push(row_id); }; diff --git a/src/dc_strencode.rs b/src/dc_strencode.rs index 91f49f375..23fe37e68 100644 --- a/src/dc_strencode.rs +++ b/src/dc_strencode.rs @@ -1,30 +1,17 @@ use itertools::Itertools; -use std::borrow::Cow; -use std::ffi::CString; -use std::ptr; -use charset::Charset; -use libc::free; -use mmime::mailmime::decode::mailmime_encoded_phrase_parse; -use mmime::other::*; -use percent_encoding::{percent_decode, utf8_percent_encode, AsciiSet, CONTROLS}; - -use crate::dc_tools::*; - -/** - * Encode non-ascii-strings as `=?UTF-8?Q?Bj=c3=b6rn_Petersen?=`. - * Belongs to RFC 2047: https://tools.ietf.org/html/rfc2047 - * - * We do not fold at position 72; this would result in empty words as `=?utf-8?Q??=` which are correct, - * but cannot be displayed by some mail programs (eg. Android Stock Mail). - * however, this is not needed, as long as _one_ word is not longer than 72 characters. - * _if_ it is, the display may get weird. This affects the subject only. - * the best solution wor all this would be if libetpan encodes the line as only libetpan knowns when a header line is full. - * - * @param to_encode Null-terminated UTF-8-string to encode. - * @return Returns the encoded string which must be free()'d when no longed needed. - * On errors, NULL is returned. - */ +/// Encode non-ascii-strings as `=?UTF-8?Q?Bj=c3=b6rn_Petersen?=`. +/// Belongs to RFC 2047: https://tools.ietf.org/html/rfc2047 +/// +/// We do not fold at position 72; this would result in empty words as `=?utf-8?Q??=` which are correct, +/// but cannot be displayed by some mail programs (eg. Android Stock Mail). +/// however, this is not needed, as long as _one_ word is not longer than 72 characters. +/// _if_ it is, the display may get weird. This affects the subject only. +/// the best solution wor all this would be if libetpan encodes the line as only libetpan knowns when a header line is full. +/// +/// @param to_encode Null-terminated UTF-8-string to encode. +/// @return Returns the encoded string which must be free()'d when no longed needed. +/// On errors, NULL is returned. pub fn dc_encode_header_words(input: impl AsRef) -> String { let mut result = String::default(); for (_, group) in &input.as_ref().chars().group_by(|c| c.is_whitespace()) { @@ -68,31 +55,6 @@ fn quote_word(word: &[u8]) -> String { * Encode/decode header words, RFC 2047 ******************************************************************************/ -pub(crate) fn dc_decode_header_words(input: &str) -> String { - static FROM_ENCODING: &[u8] = b"iso-8859-1\x00"; - static TO_ENCODING: &[u8] = b"utf-8\x00"; - let mut out = ptr::null_mut(); - let mut cur_token = 0; - let input_c = CString::yolo(input); - unsafe { - let r = mailmime_encoded_phrase_parse( - FROM_ENCODING.as_ptr().cast(), - input_c.as_ptr(), - input.len(), - &mut cur_token, - TO_ENCODING.as_ptr().cast(), - &mut out, - ); - if r as u32 != MAILIMF_NO_ERROR || out.is_null() { - input.to_string() - } else { - let res = to_string_lossy(out); - free(out.cast()); - res - } - } -} - pub fn dc_needs_ext_header(to_check: impl AsRef) -> bool { let to_check = to_check.as_ref(); @@ -110,142 +72,3 @@ pub fn dc_needs_ext_header(to_check: impl AsRef) -> bool { || c == '%') }) } - -const EXT_ASCII_ST: &AsciiSet = &CONTROLS - .add(b' ') - .add(b'-') - .add(b'_') - .add(b'.') - .add(b'~') - .add(b'%'); - -/// Encode an UTF-8 string to the extended header format. -pub fn dc_encode_ext_header(to_encode: impl AsRef) -> String { - let encoded = utf8_percent_encode(to_encode.as_ref(), &EXT_ASCII_ST); - format!("utf-8''{}", encoded) -} - -/// Decode an extended-header-format strings to UTF-8. -pub fn dc_decode_ext_header(to_decode: &[u8]) -> Cow { - if let Some(index) = bytes!(b'\'').find(to_decode) { - let (charset, rest) = to_decode.split_at(index); - if !charset.is_empty() { - // skip language - if let Some(index2) = bytes!(b'\'').find(&rest[1..]) { - let decoded = percent_decode(&rest[index2 + 2..]); - - if charset != b"utf-8" && charset != b"UTF-8" { - if let Some(encoding) = Charset::for_label(charset) { - let bytes = decoded.collect::>(); - let (res, _, _) = encoding.decode(&bytes); - return Cow::Owned(res.into_owned()); - } else { - return decoded.decode_utf8_lossy(); - } - } else { - return decoded.decode_utf8_lossy(); - } - } - } - } - - String::from_utf8_lossy(to_decode) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_dc_decode_header_words() { - assert_eq!( - dc_decode_header_words("=?utf-8?B?dGVzdMOkw7bDvC50eHQ=?="), - std::string::String::from_utf8(b"test\xc3\xa4\xc3\xb6\xc3\xbc.txt".to_vec()).unwrap(), - ); - - assert_eq!(dc_decode_header_words("just ascii test"), "just ascii test"); - - assert_eq!(dc_encode_header_words("abcdef"), "abcdef"); - - let r = dc_encode_header_words( - std::string::String::from_utf8(b"test\xc3\xa4\xc3\xb6\xc3\xbc.txt".to_vec()).unwrap(), - ); - assert!(r.starts_with("=?utf-8")); - - assert_eq!( - dc_decode_header_words(&r), - std::string::String::from_utf8(b"test\xc3\xa4\xc3\xb6\xc3\xbc.txt".to_vec()).unwrap(), - ); - - assert_eq!( - dc_decode_header_words("=?ISO-8859-1?Q?attachment=3B=0D=0A_filename=3D?= =?ISO-8859-1?Q?=22test=E4=F6=FC=2Etxt=22=3B=0D=0A_size=3D39?="), - std::string::String::from_utf8(b"attachment;\r\n filename=\"test\xc3\xa4\xc3\xb6\xc3\xbc.txt\";\r\n size=39".to_vec()).unwrap(), - ); - } - - #[test] - fn test_dc_encode_ext_header() { - let buf1 = dc_encode_ext_header("Björn Petersen"); - assert_eq!(&buf1, "utf-8\'\'Bj%C3%B6rn%20Petersen"); - let buf2 = dc_decode_ext_header(buf1.as_bytes()); - assert_eq!(&buf2, "Björn Petersen",); - - let buf1 = dc_decode_ext_header(b"iso-8859-1\'en\'%A3%20rates"); - assert_eq!(buf1, "£ rates",); - - let buf1 = dc_decode_ext_header(b"wrong\'format"); - assert_eq!(buf1, "wrong\'format",); - - let buf1 = dc_decode_ext_header(b"\'\'"); - assert_eq!(buf1, "\'\'"); - - let buf1 = dc_decode_ext_header(b"x\'\'"); - assert_eq!(buf1, ""); - - let buf1 = dc_decode_ext_header(b"\'"); - assert_eq!(buf1, "\'"); - - let buf1 = dc_decode_ext_header(b""); - assert_eq!(buf1, ""); - - // regressions - assert_eq!( - dc_decode_ext_header(dc_encode_ext_header("%0A").as_bytes()), - "%0A" - ); - } - - #[test] - fn test_dc_needs_ext_header() { - assert_eq!(dc_needs_ext_header("Björn"), true); - assert_eq!(dc_needs_ext_header("Bjoern"), false); - assert_eq!(dc_needs_ext_header(""), false); - assert_eq!(dc_needs_ext_header(" "), true); - assert_eq!(dc_needs_ext_header("a b"), true); - } - - use proptest::prelude::*; - - proptest! { - #[test] - fn test_ext_header_roundtrip(buf: String) { - let encoded = dc_encode_ext_header(&buf); - let decoded = dc_decode_ext_header(encoded.as_bytes()); - assert_eq!(buf, decoded); - } - - #[test] - fn test_ext_header_decode_anything(buf: Vec) { - // make sure this never panics - let _decoded = dc_decode_ext_header(&buf); - } - - #[test] - fn test_dc_header_roundtrip(input: String) { - let encoded = dc_encode_header_words(&input); - let decoded = dc_decode_header_words(&encoded); - - assert_eq!(input, decoded); - } - } -} diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 255e73a2a..08f58296c 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -3,54 +3,22 @@ use core::cmp::{max, min}; use std::borrow::Cow; -use std::ffi::{CStr, CString}; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::time::SystemTime; -use std::{fmt, fs, ptr}; +use std::{fmt, fs}; use chrono::{Local, TimeZone}; -use libc::{memcpy, strlen}; -use mmime::clist::*; -use mmime::mailimf::types::*; use rand::{thread_rng, Rng}; use crate::context::Context; use crate::error::Error; use crate::events::Event; -pub(crate) fn dc_exactly_one_bit_set(v: libc::c_int) -> bool { +pub(crate) fn dc_exactly_one_bit_set(v: i32) -> bool { 0 != v && 0 == v & (v - 1) } -/// Duplicates a string -/// -/// returns an empty string if NULL is given, never returns NULL (exits on errors) -/// -/// # Examples -/// -/// ``` -/// use deltachat::dc_tools::{dc_strdup, to_string_lossy}; -/// unsafe { -/// let str_a = b"foobar\x00" as *const u8 as *const libc::c_char; -/// let str_a_copy = dc_strdup(str_a); -/// assert_eq!(to_string_lossy(str_a_copy), "foobar"); -/// assert_ne!(str_a, str_a_copy); -/// } -/// ``` -pub unsafe fn dc_strdup(s: *const libc::c_char) -> *mut libc::c_char { - let ret: *mut libc::c_char; - if !s.is_null() { - ret = strdup(s); - assert!(!ret.is_null()); - } else { - ret = libc::calloc(1, 1) as *mut libc::c_char; - assert!(!ret.is_null()); - } - - ret -} - /// Shortens a string to a specified length and adds "..." or "[...]" to the end of /// the shortened string. pub(crate) fn dc_truncate(buf: &str, approx_chars: usize, do_unwrap: bool) -> Cow { @@ -74,36 +42,12 @@ pub(crate) fn dc_truncate(buf: &str, approx_chars: usize, do_unwrap: bool) -> Co } } -pub(crate) fn dc_str_from_clist(list: *const clist, delimiter: &str) -> String { - let mut res = String::new(); - - if !list.is_null() { - for rfc724_mid in unsafe { (*list).into_iter() } { - if !res.is_empty() { - res += delimiter; - } - res += &to_string_lossy(rfc724_mid as *const libc::c_char); - } - } - res -} - -pub(crate) fn dc_str_to_clist(str: &str, delimiter: &str) -> *mut clist { - unsafe { - let list: *mut clist = clist_new(); - for cur in str.split(&delimiter) { - clist_insert_after(list, (*list).last, cur.strdup().cast()); - } - list - } -} - -/* the colors must fulfill some criterions as: -- contrast to black and to white -- work as a text-color -- being noticeable on a typical map -- harmonize together while being different enough -(therefore, we cannot just use random rgb colors :) */ +/// the colors must fulfill some criterions as: +/// - contrast to black and to white +/// - work as a text-color +/// - being noticeable on a typical map +/// - harmonize together while being different enough +/// (therefore, we cannot just use random rgb colors :) const COLORS: [u32; 16] = [ 0xe56555, 0xf28c48, 0x8e85ee, 0x76c84d, 0x5bb6cc, 0x549cdd, 0xd25c99, 0xb37800, 0xf23030, 0x39b249, 0xbb243b, 0x964078, 0x66874f, 0x308ab9, 0x127ed0, 0xbe450c, @@ -122,33 +66,6 @@ pub(crate) fn dc_str_to_color(s: impl AsRef) -> u32 { COLORS[color_index] } -/* date/time tools */ -/* the result is UTC or DC_INVALID_TIMESTAMP */ -pub(crate) fn dc_timestamp_from_date(date_time: *mut mailimf_date_time) -> i64 { - assert!(!date_time.is_null()); - let dt = unsafe { *date_time }; - - let sec = dt.dt_sec; - let min = dt.dt_min; - let hour = dt.dt_hour; - let day = dt.dt_day; - let month = dt.dt_month; - let year = dt.dt_year; - - let ts = chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd(year, month as u32, day as u32), - chrono::NaiveTime::from_hms(hour as u32, min as u32, sec as u32), - ); - - let (zone_hour, zone_min) = if dt.dt_zone >= 0 { - (dt.dt_zone / 100, dt.dt_zone % 100) - } else { - (-(-dt.dt_zone / 100), -(-dt.dt_zone % 100)) - }; - - ts.timestamp() - (zone_hour * 3600 + zone_min * 60) as i64 -} - /* ****************************************************************************** * date/time tools ******************************************************************************/ @@ -318,22 +235,6 @@ pub(crate) fn dc_extract_grpid_from_rfc724_mid(mid: &str) -> Option<&str> { None } -pub(crate) fn dc_extract_grpid_from_rfc724_mid_list(list: *const clist) -> *mut libc::c_char { - if !list.is_null() { - unsafe { - for cur in (*list).into_iter() { - let mid = to_string_lossy(cur as *const libc::c_char); - - if let Some(grpid) = dc_extract_grpid_from_rfc724_mid(&mid) { - return grpid.strdup(); - } - } - } - } - - ptr::null_mut() -} - pub(crate) fn dc_ensure_no_slash_safe(path: &str) -> &str { if path.ends_with('/') || path.ends_with('\\') { return &path[..path.len() - 1]; @@ -601,212 +502,6 @@ pub(crate) fn dc_get_next_backup_path( bail!("could not create backup file, disk full?"); } -/// Error type for the [OsStrExt] trait -#[derive(Debug, Fail, PartialEq)] -pub enum CStringError { - /// The string contains an interior null byte - #[fail(display = "String contains an interior null byte")] - InteriorNullByte, - /// The string is not valid Unicode - #[fail(display = "String is not valid unicode")] - NotUnicode, -} - -/// Extra convenience methods on [std::ffi::OsStr] to work with `*libc::c_char`. -/// -/// The primary function of this trait is to more easily convert -/// [OsStr], [OsString] or [Path] into pointers to C strings. This always -/// allocates a new string since it is very common for the source -/// string not to have the required terminal null byte. -/// -/// It is implemented for `AsRef>` trait, which -/// allows any type which implements this trait to transparently use -/// this. This is how the conversion for [Path] works. -/// -/// [OsStr]: std::ffi::OsStr -/// [OsString]: std::ffi::OsString -/// [Path]: std::path::Path -/// -/// # Example -/// -/// ``` -/// use deltachat::dc_tools::{dc_strdup, OsStrExt}; -/// let path = std::path::Path::new("/some/path"); -/// let path_c = path.to_c_string().unwrap(); -/// unsafe { -/// let mut c_ptr: *mut libc::c_char = dc_strdup(path_c.as_ptr()); -/// } -/// ``` -pub trait OsStrExt { - /// Convert a [std::ffi::OsStr] to an [std::ffi::CString] - /// - /// This is useful to convert e.g. a [std::path::Path] to - /// [*libc::c_char] by using - /// [Path::as_os_str()](std::path::Path::as_os_str) and - /// [CStr::as_ptr()](std::ffi::CStr::as_ptr). - /// - /// This returns [CString] and not [&CStr] because not all [OsStr] - /// slices end with a null byte, particularly those coming from - /// [Path] do not have a null byte and having to handle this as - /// the caller would defeat the point of this function. - /// - /// On Windows this requires that the [OsStr] contains valid - /// unicode, which should normally be the case for a [Path]. - /// - /// [CString]: std::ffi::CString - /// [CStr]: std::ffi::CStr - /// [OsStr]: std::ffi::OsStr - /// [Path]: std::path::Path - /// - /// # Errors - /// - /// Since a C `*char` is terminated by a NULL byte this conversion - /// will fail, when the [OsStr] has an interior null byte. The - /// function will return - /// `[Err]([CStringError::InteriorNullByte])`. When converting - /// from a [Path] it should be safe to - /// [`.unwrap()`](std::result::Result::unwrap) this anyway since a - /// [Path] should not contain interior null bytes. - /// - /// On windows when the string contains invalid Unicode - /// `[Err]([CStringError::NotUnicode])` is returned. - fn to_c_string(&self) -> Result; -} - -impl> OsStrExt for T { - #[cfg(not(target_os = "windows"))] - fn to_c_string(&self) -> Result { - use std::os::unix::ffi::OsStrExt; - CString::new(self.as_ref().as_bytes()).map_err(|err| match err { - std::ffi::NulError { .. } => CStringError::InteriorNullByte, - }) - } - - #[cfg(target_os = "windows")] - fn to_c_string(&self) -> Result { - os_str_to_c_string_unicode(&self) - } -} - -// Implementation for os_str_to_c_string on windows. -#[allow(dead_code)] -fn os_str_to_c_string_unicode( - os_str: &dyn AsRef, -) -> Result { - match os_str.as_ref().to_str() { - Some(val) => CString::new(val.as_bytes()).map_err(|err| match err { - std::ffi::NulError { .. } => CStringError::InteriorNullByte, - }), - None => Err(CStringError::NotUnicode), - } -} - -/// Convenience methods/associated functions for working with [CString] -/// -/// This is helps transitioning from unsafe code. -pub trait CStringExt { - /// Create a new [CString], yolo style - /// - /// This unwrap the result, panicking when there are embedded NULL - /// bytes. - fn yolo>>(t: T) -> CString { - CString::new(t).expect("String contains null byte, can not be CString") - } -} - -impl CStringExt for CString {} - -/// Convenience methods to make transitioning from raw C strings easier. -/// -/// To interact with (legacy) C APIs we often need to convert from -/// Rust strings to raw C strings. This can be clumsy to do correctly -/// and the compiler sometimes allows it in an unsafe way. These -/// methods make it more succinct and help you get it right. -pub trait StrExt { - /// Allocate a new raw C `*char` version of this string. - /// - /// This allocates a new raw C string which must be freed using - /// `free`. It takes care of some common pitfalls with using - /// [CString.as_ptr]. - /// - /// [CString.as_ptr]: std::ffi::CString.as_ptr - /// - /// # Panics - /// - /// This function will panic when the original string contains an - /// interior null byte as this can not be represented in raw C - /// strings. - unsafe fn strdup(&self) -> *mut libc::c_char; -} - -impl> StrExt for T { - unsafe fn strdup(&self) -> *mut libc::c_char { - let tmp = CString::yolo(self.as_ref()); - dc_strdup(tmp.as_ptr()) - } -} - -pub fn to_string_lossy(s: *const libc::c_char) -> String { - if s.is_null() { - return "".into(); - } - - let cstr = unsafe { CStr::from_ptr(s) }; - - cstr.to_string_lossy().to_string() -} - -pub fn to_opt_string_lossy(s: *const libc::c_char) -> Option { - if s.is_null() { - return None; - } - - Some(to_string_lossy(s)) -} - -/// Convert a C `*char` pointer to a [std::path::Path] slice. -/// -/// This converts a `*libc::c_char` pointer to a [Path] slice. This -/// essentially has to convert the pointer to [std::ffi::OsStr] to do -/// so and thus is the inverse of [OsStrExt::to_c_string]. Just like -/// [OsStrExt::to_c_string] requires valid Unicode on Windows, this -/// requires that the pointer contains valid UTF-8 on Windows. -/// -/// Because this returns a reference the [Path] silce can not outlive -/// the original pointer. -/// -/// [Path]: std::path::Path -#[cfg(not(target_os = "windows"))] -pub fn as_path<'a>(s: *const libc::c_char) -> &'a std::path::Path { - assert!(!s.is_null(), "cannot be used on null pointers"); - use std::os::unix::ffi::OsStrExt; - unsafe { - let c_str = std::ffi::CStr::from_ptr(s).to_bytes(); - let os_str = std::ffi::OsStr::from_bytes(c_str); - std::path::Path::new(os_str) - } -} - -// as_path() implementation for windows, documented above. -#[cfg(target_os = "windows")] -pub fn as_path<'a>(s: *const libc::c_char) -> &'a std::path::Path { - as_path_unicode(s) -} - -// Implementation for as_path() on Windows. -// -// Having this as a separate function means it can be tested on unix -// too. -#[allow(dead_code)] -fn as_path_unicode<'a>(s: *const libc::c_char) -> &'a std::path::Path { - assert!(!s.is_null(), "cannot be used on null pointers"); - - let cstr = unsafe { CStr::from_ptr(s) }; - let str = cstr.to_str().unwrap_or_else(|err| panic!("{}", err)); - - std::path::Path::new(str) -} - pub(crate) fn time() -> i64 { SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) @@ -884,71 +579,14 @@ pub(crate) fn listflags_has(listflags: u32, bitindex: usize) -> bool { (listflags & bitindex) == bitindex } -pub(crate) unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char { - if s.is_null() { - return std::ptr::null_mut(); - } - - let slen = strlen(s); - let result = libc::malloc(slen + 1); - if result.is_null() { - return std::ptr::null_mut(); - } - - memcpy(result, s as *const _, slen + 1); - result as *mut _ -} - -pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char) -> libc::c_int { - let s1 = std::ffi::CStr::from_ptr(s1) - .to_string_lossy() - .to_lowercase(); - let s2 = std::ffi::CStr::from_ptr(s2) - .to_string_lossy() - .to_lowercase(); - if s1 == s2 { - 0 - } else { - 1 - } -} - #[cfg(test)] mod tests { use super::*; - - use libc::{free, strcmp}; use std::convert::TryInto; - use std::ffi::CStr; use crate::constants::*; use crate::test_utils::*; - #[test] - fn test_dc_strdup() { - unsafe { - let str_a = b"foobar\x00" as *const u8 as *const libc::c_char; - let str_a_copy = dc_strdup(str_a); - - // Value of str_a_copy should equal foobar - assert_eq!( - CStr::from_ptr(str_a_copy), - CString::new("foobar").unwrap().as_c_str() - ); - // Address of str_a should be different from str_a_copy - assert_ne!(str_a, str_a_copy); - - let str_a = std::ptr::null() as *const libc::c_char; - let str_a_copy = dc_strdup(str_a); - // Value of str_a_copy should equal "" - assert_eq!( - CStr::from_ptr(str_a_copy), - CString::new("").unwrap().as_c_str() - ); - assert_ne!(str_a, str_a_copy); - } - } - #[test] fn test_rust_ftoa() { assert_eq!("1.22", format!("{}", 1.22)); @@ -1009,44 +647,6 @@ mod tests { ); } - /* calls free() for each item content */ - unsafe fn clist_free_content(haystack: *const clist) { - let mut iter = (*haystack).first; - - while !iter.is_null() { - free((*iter).data); - (*iter).data = ptr::null_mut(); - iter = if !iter.is_null() { - (*iter).next - } else { - ptr::null_mut() - } - } - } - - #[test] - fn test_dc_str_to_clist_1() { - unsafe { - let list = dc_str_to_clist("", " "); - assert_eq!((*list).count, 1); - clist_free_content(list); - clist_free(list); - } - } - - #[test] - fn test_dc_str_to_clist_4() { - unsafe { - let list: *mut clist = dc_str_to_clist("foo bar test", " "); - assert_eq!((*list).count, 3); - let str = dc_str_from_clist(list, " "); - assert_eq!(str, "foo bar test"); - - clist_free_content(list); - clist_free(list); - } - } - #[test] fn test_dc_create_id() { let buf = dc_create_id(); @@ -1074,113 +674,6 @@ mod tests { } #[test] - fn test_os_str_to_c_string_cwd() { - let some_dir = std::env::current_dir().unwrap(); - some_dir.as_os_str().to_c_string().unwrap(); - } - - #[test] - fn test_os_str_to_c_string_unicode() { - let some_str = String::from("/some/valid/utf8"); - let some_dir = std::path::Path::new(&some_str); - assert_eq!( - some_dir.as_os_str().to_c_string().unwrap(), - CString::new("/some/valid/utf8").unwrap() - ); - } - - #[test] - fn test_os_str_to_c_string_nul() { - let some_str = std::ffi::OsString::from("foo\x00bar"); - assert_eq!( - some_str.to_c_string().err().unwrap(), - CStringError::InteriorNullByte - ) - } - - #[test] - fn test_path_to_c_string_cwd() { - let some_dir = std::env::current_dir().unwrap(); - some_dir.to_c_string().unwrap(); - } - - #[test] - fn test_path_to_c_string_unicode() { - let some_str = String::from("/some/valid/utf8"); - let some_dir = std::path::Path::new(&some_str); - assert_eq!( - some_dir.as_os_str().to_c_string().unwrap(), - CString::new("/some/valid/utf8").unwrap() - ); - } - - #[test] - fn test_os_str_to_c_string_unicode_fn() { - let some_str = std::ffi::OsString::from("foo"); - assert_eq!( - os_str_to_c_string_unicode(&some_str).unwrap(), - CString::new("foo").unwrap() - ); - } - - #[test] - fn test_path_to_c_string_unicode_fn() { - let some_str = String::from("/some/path"); - let some_path = std::path::Path::new(&some_str); - assert_eq!( - os_str_to_c_string_unicode(&some_path).unwrap(), - CString::new("/some/path").unwrap() - ); - } - - #[test] - fn test_os_str_to_c_string_unicode_fn_nul() { - let some_str = std::ffi::OsString::from("fooz\x00bar"); - assert_eq!( - os_str_to_c_string_unicode(&some_str).err().unwrap(), - CStringError::InteriorNullByte - ); - } - - #[test] - fn test_as_path() { - let some_path = CString::new("/some/path").unwrap(); - let ptr = some_path.as_ptr(); - assert_eq!(as_path(ptr), std::ffi::OsString::from("/some/path")) - } - - #[test] - fn test_as_path_unicode_fn() { - let some_path = CString::new("/some/path").unwrap(); - let ptr = some_path.as_ptr(); - assert_eq!(as_path_unicode(ptr), std::ffi::OsString::from("/some/path")); - } - - #[test] - fn test_cstring_yolo() { - assert_eq!(CString::new("hello").unwrap(), CString::yolo("hello")); - } - - #[test] - fn test_strdup_str() { - unsafe { - let s = "hello".strdup(); - let cmp = strcmp(s, b"hello\x00" as *const u8 as *const libc::c_char); - free(s as *mut libc::c_void); - assert_eq!(cmp, 0); - } - } - - #[test] - fn test_strdup_string() { - unsafe { - let s = String::from("hello").strdup(); - let cmp = strcmp(s, b"hello\x00" as *const u8 as *const libc::c_char); - free(s as *mut libc::c_void); - assert_eq!(cmp, 0); - } - } - #[test] fn test_dc_extract_grpid_from_rfc724_mid() { // Should return None if we pass invalid mid diff --git a/src/e2ee.rs b/src/e2ee.rs index 76e611a39..e207fa1c3 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -1,41 +1,20 @@ //! End-to-end encryption support. use std::collections::HashSet; -use std::ptr; -use std::str::FromStr; -use libc::strlen; -use mmime::clist::*; -use mmime::mailimf::types::*; -use mmime::mailimf::types_helper::*; -use mmime::mailimf::*; -use mmime::mailmime::content::*; -use mmime::mailmime::types::*; -use mmime::mailmime::types_helper::*; -use mmime::mailmime::write_mem::*; -use mmime::mailmime::*; -use mmime::mailprivacy_prepare_mime; -use mmime::mmapstring::*; -use mmime::{mailmime_substitute, MAILIMF_NO_ERROR, MAIL_NO_ERROR}; +use mailparse::MailHeaderMap; use num_traits::FromPrimitive; use crate::aheader::*; use crate::config::Config; use crate::context::Context; -use crate::dc_tools::*; use crate::error::*; use crate::key::*; use crate::keyring::*; -use crate::mimefactory::MimeFactory; use crate::peerstate::*; use crate::pgp; use crate::securejoin::handle_degrade_event; use crate::wrapmime; -use crate::wrapmime::*; - -// standard mime-version header aka b"Version: 1\r\n\x00" -static mut VERSION_CONTENT: [libc::c_char; 13] = - [86, 101, 114, 115, 105, 111, 110, 58, 32, 49, 13, 10, 0]; #[derive(Debug)] pub struct EncryptHelper { @@ -71,39 +50,27 @@ impl EncryptHelper { Aheader::new(addr, pk, self.prefer_encrypt) } - pub fn try_encrypt( - &mut self, - factory: &mut MimeFactory, + /// Determines if we can and should encrypt. + pub fn should_encrypt( + &self, + context: &Context, e2ee_guaranteed: bool, - min_verified: PeerstateVerifiedStatus, - do_gossip: bool, - mut in_out_message: *mut Mailmime, - imffields_unprotected: *mut mailimf_fields, + peerstates: &[(Option, &str)], ) -> Result { - // libEtPan's pgp_encrypt_mime() takes the parent as the new root. - // We just expect the root as being given to this function. - ensure!( - !in_out_message.is_null() && unsafe { (*in_out_message).mm_parent.is_null() }, - "corrupted inputs" - ); - if !(self.prefer_encrypt == EncryptPreference::Mutual || e2ee_guaranteed) { return Ok(false); } - let context = &factory.context; - let mut keyring = Keyring::default(); - let mut gossip_headers: Vec = Vec::with_capacity(factory.recipients_addr.len()); - - // determine if we can and should encrypt - for recipient_addr in factory.recipients_addr.iter() { - if recipient_addr == &self.addr { - continue; - } - let peerstate = match Peerstate::from_addr(context, &context.sql, recipient_addr) { - Some(peerstate) => peerstate, + for (peerstate, addr) in peerstates { + match peerstate { + Some(peerstate) => { + if peerstate.prefer_encrypt != EncryptPreference::Mutual && !e2ee_guaranteed { + info!(context, "peerstate for {:?} is no-encrypt", addr); + return Ok(false); + } + } None => { - let msg = format!("peerstate for {} missing, cannot encrypt", recipient_addr); + let msg = format!("peerstate for {:?} missing, cannot encrypt", addr); if e2ee_guaranteed { return Err(format_err!("{}", msg)); } else { @@ -111,169 +78,62 @@ impl EncryptHelper { return Ok(false); } } - }; - - if peerstate.prefer_encrypt != EncryptPreference::Mutual && !e2ee_guaranteed { - info!(context, "peerstate for {} is no-encrypt", recipient_addr); - return Ok(false); - } - - if let Some(key) = peerstate.peek_key(min_verified) { - keyring.add_owned(key.clone()); - if do_gossip { - if let Some(header) = peerstate.render_gossip_header(min_verified) { - gossip_headers.push(header.to_string()); - } - } - } else { - bail!( - "proper enc-key for {} missing, cannot encrypt", - recipient_addr - ); } } - let sign_key = { - keyring.add_ref(&self.public_key); - let key = Key::from_self_private(context, self.addr.clone(), &context.sql); - ensure!(key.is_some(), "no own private key found"); + Ok(true) + } - key - }; + /// Tries to encrypt the passed in `mail`. + pub fn encrypt( + &mut self, + context: &Context, + min_verified: PeerstateVerifiedStatus, + mail_to_encrypt: lettre_email::PartBuilder, + peerstates: &[(Option, &str)], + ) -> Result { + let mut keyring = Keyring::default(); - // encrypt message - unsafe { - mailprivacy_prepare_mime(in_out_message); - let mut part_to_encrypt = (*in_out_message).mm_data.mm_message.mm_msg_mime; - (*part_to_encrypt).mm_parent = ptr::null_mut(); - let imffields_encrypted = mailimf_fields_new_empty(); - - // mailmime_new_message_data() calls mailmime_fields_new_with_version() - // which would add the unwanted MIME-Version:-header - let message_to_encrypt = mailmime_new_simple( - MAILMIME_MESSAGE as libc::c_int, - mailmime_fields_new_empty(), - mailmime_get_content_message(), - imffields_encrypted, - part_to_encrypt, - ); - - for header in &gossip_headers { - wrapmime::new_custom_field(imffields_encrypted, "Autocrypt-Gossip", &header) - } - - // memoryhole headers: move some headers into encrypted part - // XXX note we can't use clist's into_iter() because the loop body also removes items - let mut cur = (*(*imffields_unprotected).fld_list).first; - while !cur.is_null() { - let field = (*cur).data as *mut mailimf_field; - let mut move_to_encrypted = false; - - if !field.is_null() { - if (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int { - move_to_encrypted = true; - } else if (*field).fld_type == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int { - let opt_field = (*field).fld_data.fld_optional_field; - if !opt_field.is_null() && !(*opt_field).fld_name.is_null() { - let fld_name = to_string_lossy((*opt_field).fld_name); - if fld_name.starts_with("Secure-Join") - || (fld_name.starts_with("Chat-") && fld_name != "Chat-Version") - { - move_to_encrypted = true; - } - } - } - } - - if move_to_encrypted { - mailimf_fields_add(imffields_encrypted, field); - cur = clist_delete((*imffields_unprotected).fld_list, cur); - } else { - cur = (*cur).next; - } - } - - let subject = mailimf_subject_new("...".strdup()); - mailimf_fields_add(imffields_unprotected, mailimf_field_new_subject(subject)); - - wrapmime::append_ct_param( - (*part_to_encrypt).mm_content_type, - "protected-headers", - "v1", - )?; - let plain = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char); - let mut col = 0; - mailmime_write_mem(plain, &mut col, message_to_encrypt); - mailmime_free(message_to_encrypt); - - ensure!( - !(*plain).str_0.is_null() && (*plain).len > 0, - "could not write/allocate" - ); - - let ctext = pgp::pk_encrypt( - std::slice::from_raw_parts((*plain).str_0 as *const u8, (*plain).len), - &keyring, - sign_key.as_ref(), - ); - mmap_string_free(plain); - - let ctext_v = ctext?; - - // create MIME-structure that will contain the encrypted text - let mut encrypted_part = new_data_part( - ptr::null_mut(), - 0 as libc::size_t, - "multipart/encrypted", - MAILMIME_MECHANISM_BASE64, - )?; - let content = (*encrypted_part).mm_content_type; - wrapmime::append_ct_param(content, "protocol", "application/pgp-encrypted")?; - - let version_mime = new_data_part( - VERSION_CONTENT.as_mut_ptr() as *mut libc::c_void, - strlen(VERSION_CONTENT.as_mut_ptr()), - "application/pgp-encrypted", - MAILMIME_MECHANISM_7BIT, - )?; - mailmime_smart_add_part(encrypted_part, version_mime); - - // we assume that ctext_v is not dropped until the end - // of this if-scope - let ctext_part = new_data_part( - ctext_v.as_ptr() as *mut libc::c_void, - ctext_v.len(), - "application/octet-stream", - MAILMIME_MECHANISM_7BIT, - )?; - - mailmime_smart_add_part(encrypted_part, ctext_part); - (*in_out_message).mm_data.mm_message.mm_msg_mime = encrypted_part; - (*encrypted_part).mm_parent = in_out_message; - let gossiped = !&gossip_headers.is_empty(); - factory.finalize_mime_message(in_out_message, true, gossiped)?; - - Ok(true) + for (peerstate, addr) in peerstates + .iter() + .filter_map(|(state, addr)| state.as_ref().map(|s| (s, addr))) + { + info!(context, "adding for {}: {:?}", addr, peerstate); + let key = peerstate.peek_key(min_verified).ok_or_else(|| { + format_err!("proper enc-key for {} missing, cannot encrypt", addr) + })?; + keyring.add_ref(key); } + + keyring.add_ref(&self.public_key); + let sign_key = Key::from_self_private(context, self.addr.clone(), &context.sql) + .ok_or_else(|| format_err!("missing own private key"))?; + + let raw_message = mail_to_encrypt.build().as_string().into_bytes(); + + let ctext = pgp::pk_encrypt(&raw_message, &keyring, Some(&sign_key))?; + + Ok(ctext) } } pub fn try_decrypt( context: &Context, - in_out_message: *mut Mailmime, -) -> Result<(bool, HashSet, HashSet)> { - // just a pointer into mailmime structure, must not be freed - let imffields = mailmime_find_mailimf_fields(in_out_message); - ensure!( - !in_out_message.is_null() && !imffields.is_null(), - "corrupt invalid mime inputs" - ); + mail: &mailparse::ParsedMail<'_>, + message_time: i64, +) -> Result<(Option>, HashSet)> { + info!(context, "trying to decrypt"); - let from = wrapmime::get_field_from(imffields)?; - let message_time = wrapmime::get_field_date(imffields)?; + let from = mail + .headers + .get_first_value("From")? + .and_then(|from_addr| mailparse::addrparse(&from_addr).ok()) + .and_then(|from| from.extract_single_info()) + .map(|from| from.addr) + .unwrap_or_default(); let mut peerstate = None; - let autocryptheader = Aheader::from_imffields(&from, imffields); + let autocryptheader = Aheader::from_headers(context, &from, &mail.headers); if message_time > 0 { peerstate = Peerstate::from_addr(context, &context.sql, &from); @@ -282,9 +142,7 @@ pub fn try_decrypt( if let Some(ref header) = autocryptheader { peerstate.apply_header(&header, message_time); peerstate.save_to_db(&context.sql, false)?; - } else if message_time > peerstate.last_seen_autocrypt - && !contains_report(in_out_message) - { + } else if message_time > peerstate.last_seen_autocrypt && !contains_report(mail) { peerstate.degrade_encryption(message_time); peerstate.save_to_db(&context.sql, false)?; } @@ -294,13 +152,12 @@ pub fn try_decrypt( peerstate = Some(p); } } + /* possibly perform decryption */ let mut private_keyring = Keyring::default(); let mut public_keyring_for_validate = Keyring::default(); - let mut encrypted = false; + let mut out_mail = None; let mut signatures = HashSet::default(); - let mut gossipped_addr = HashSet::default(); - let self_addr = context.get_config(Config::ConfiguredAddr); if let Some(self_addr) = self_addr { @@ -320,60 +177,16 @@ pub fn try_decrypt( } } - let mut gossip_headers = ptr::null_mut(); - encrypted = decrypt_if_autocrypt_message( + out_mail = decrypt_if_autocrypt_message( context, - in_out_message, + mail, &private_keyring, &public_keyring_for_validate, &mut signatures, - &mut gossip_headers, )?; - if !gossip_headers.is_null() { - gossipped_addr = - update_gossip_peerstates(context, message_time, imffields, gossip_headers)?; - unsafe { mailimf_fields_free(gossip_headers) }; - } } } - Ok((encrypted, signatures, gossipped_addr)) -} - -fn new_data_part( - data: *mut libc::c_void, - data_bytes: libc::size_t, - content_type: &str, - default_encoding: u32, -) -> Result<*mut Mailmime> { - let content = new_content_type(&content_type)?; - let mut encoding = ptr::null_mut(); - if wrapmime::content_type_needs_encoding(content) { - encoding = unsafe { mailmime_mechanism_new(default_encoding as i32, ptr::null_mut()) }; - ensure!(!encoding.is_null(), "failed to create encoding"); - } - let mime_fields = { - unsafe { - mailmime_fields_new_with_data( - encoding, - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ) - } - }; - ensure!(!mime_fields.is_null(), "internal mime error"); - - let mime = unsafe { mailmime_new_empty(content, mime_fields) }; - ensure!(!mime.is_null(), "internal mime error"); - - if unsafe { (*mime).mm_type } == MAILMIME_SINGLE as libc::c_int { - if !data.is_null() && data_bytes > 0 { - unsafe { mailmime_set_body_text(mime, data as *mut libc::c_char, data_bytes) }; - } - } - - Ok(mime) + Ok((out_mail, signatures)) } /// Load public key from database or generate a new one. @@ -423,204 +236,65 @@ fn load_or_generate_self_public_key(context: &Context, self_addr: impl AsRef( context: &Context, - message_time: i64, - imffields: *mut mailimf_fields, - gossip_headers: *const mailimf_fields, -) -> Result> { - // XXX split the parsing from the modification part - let mut recipients: Option> = None; - let mut gossipped_addr: HashSet = Default::default(); - - for cur_data in unsafe { (*(*gossip_headers).fld_list).into_iter() } { - let field = cur_data as *mut mailimf_field; - if field.is_null() { - continue; - } - - let field = unsafe { *field }; - - if field.fld_type == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int { - let optional_field = unsafe { field.fld_data.fld_optional_field }; - if optional_field.is_null() { - continue; - } - - let optional_field = unsafe { *optional_field }; - if !optional_field.fld_name.is_null() - && to_string_lossy(optional_field.fld_name) == "Autocrypt-Gossip" - { - let value = to_string_lossy(optional_field.fld_value); - let gossip_header = Aheader::from_str(&value); - - if let Ok(ref header) = gossip_header { - if recipients.is_none() { - recipients = Some(mailimf_get_recipients(imffields)); - } - if recipients.as_ref().unwrap().contains(&header.addr) { - let mut peerstate = - Peerstate::from_addr(context, &context.sql, &header.addr); - if let Some(ref mut peerstate) = peerstate { - peerstate.apply_gossip(header, message_time); - peerstate.save_to_db(&context.sql, false)?; - } else { - let p = Peerstate::from_gossip(context, header, message_time); - p.save_to_db(&context.sql, true)?; - peerstate = Some(p); - } - if let Some(peerstate) = peerstate { - if peerstate.degrade_event.is_some() { - handle_degrade_event(context, &peerstate)?; - } - } - - gossipped_addr.insert(header.addr.clone()); - } else { - info!( - context, - "Ignoring gossipped \"{}\" as the address is not in To/Cc list.", - &header.addr, - ); - } - } - } - } - } - - Ok(gossipped_addr) -} - -fn decrypt_if_autocrypt_message( - context: &Context, - mime_undetermined: *mut Mailmime, + mail: &mailparse::ParsedMail<'a>, private_keyring: &Keyring, public_keyring_for_validate: &Keyring, ret_valid_signatures: &mut HashSet, - ret_gossip_headers: *mut *mut mailimf_fields, -) -> Result { - /* The returned bool is true if we detected an Autocrypt-encrypted - message and successfully decrypted it. Decryption then modifies the - passed in mime structure in place. The returned bool is false - if it was not an Autocrypt message. +) -> Result>> { + // The returned bool is true if we detected an Autocrypt-encrypted + // message and successfully decrypted it. Decryption then modifies the + // passed in mime structure in place. The returned bool is false + // if it was not an Autocrypt message. + // + // Errors are returned for failures related to decryption of AC-messages. - Errors are returned for failures related to decryption of AC-messages. - */ - ensure!(!mime_undetermined.is_null(), "Invalid mime reference"); - - let (mime, encrypted_data_part) = match wrapmime::get_autocrypt_mime(mime_undetermined) { - Err(_) => { + let encrypted_data_part = match wrapmime::get_autocrypt_mime(mail) { + Err(err) => { // not a proper autocrypt message, abort and ignore - return Ok(false); + warn!(context, "Invalid autocrypt message: {:?}", err); + return Ok(None); } Ok(res) => res, }; - let decrypted_mime = decrypt_part( + decrypt_part( context, encrypted_data_part, private_keyring, public_keyring_for_validate, ret_valid_signatures, - )?; - // decrypted_mime is a dangling pointer which we now put into mailmime's Ownership - unsafe { - mailmime_substitute(mime, decrypted_mime); - mailmime_free(mime); - } - - // finally, let's also return gossip headers - // XXX better return parsed headers so that upstream - // does not need to dive into mmime-stuff again. - unsafe { - if (*ret_gossip_headers).is_null() && !ret_valid_signatures.is_empty() { - let mut dummy: libc::size_t = 0; - let mut test: *mut mailimf_fields = ptr::null_mut(); - if mailimf_envelope_and_optional_fields_parse( - (*decrypted_mime).mm_mime_start, - (*decrypted_mime).mm_length, - &mut dummy, - &mut test, - ) == MAILIMF_NO_ERROR as libc::c_int - && !test.is_null() - { - *ret_gossip_headers = test; - } - } - } - - Ok(true) + ) } +/// Returns Ok(None) if nothing encrypted was found. fn decrypt_part( - _context: &Context, - mime: *mut Mailmime, + context: &Context, + mail: &mailparse::ParsedMail<'_>, private_keyring: &Keyring, public_keyring_for_validate: &Keyring, ret_valid_signatures: &mut HashSet, -) -> Result<*mut Mailmime> { - let mime_data: *mut mailmime_data; - let mut mime_transfer_encoding = MAILMIME_MECHANISM_BINARY as libc::c_int; - - unsafe { - mime_data = (*mime).mm_data.mm_single; - } - if !wrapmime::has_decryptable_data(mime_data) { - return Ok(ptr::null_mut()); - } - - if let Some(enc) = wrapmime::get_mime_transfer_encoding(mime) { - mime_transfer_encoding = enc; - } - - let data: Vec = wrapmime::decode_dt_data(mime_data, mime_transfer_encoding)?; - - let mut ret_decrypted_mime = ptr::null_mut(); +) -> Result>> { + info!(context, "decrypting part"); + let data = mail.get_body_raw()?; if has_decrypted_pgp_armor(&data) { // we should only have one decryption happening ensure!(ret_valid_signatures.is_empty(), "corrupt signatures"); - let plain = match pgp::pk_decrypt( + let plain = pgp::pk_decrypt( &data, &private_keyring, &public_keyring_for_validate, Some(ret_valid_signatures), - ) { - Ok(plain) => { - ensure!(!ret_valid_signatures.is_empty(), "no valid signatures"); - plain - } - Err(err) => bail!("could not decrypt: {}", err), - }; - let plain_bytes = plain.len(); - let plain_buf = plain.as_ptr() as *const libc::c_char; + )?; - let mut index = 0; - let mut decrypted_mime = ptr::null_mut(); - if unsafe { - mailmime_parse( - plain_buf as *const _, - plain_bytes, - &mut index, - &mut decrypted_mime, - ) - } != MAIL_NO_ERROR as libc::c_int - || decrypted_mime.is_null() - { - if !decrypted_mime.is_null() { - unsafe { mailmime_free(decrypted_mime) }; - } - } else { - // decrypted_mime points into `plain`. - // FIXME(@dignifiedquire): this still leaks memory I believe, as mailmime_free - // does not free the underlying buffer. But for now we have to live with it - std::mem::forget(plain); - ret_decrypted_mime = decrypted_mime; - } + ensure!(!ret_valid_signatures.is_empty(), "no valid signatures"); + return Ok(Some(plain)); } - Ok(ret_decrypted_mime) + Ok(None) } fn has_decrypted_pgp_armor(input: &[u8]) -> bool { @@ -644,36 +318,8 @@ fn has_decrypted_pgp_armor(input: &[u8]) -> bool { /// However, Delta Chat itself has no problem with encrypted multipart/report /// parts and MUAs should be encouraged to encrpyt multipart/reports as well so /// that we could use the normal Autocrypt processing. -fn contains_report(mime: *mut Mailmime) -> bool { - assert!(!mime.is_null()); - let mime = unsafe { *mime }; - - if mime.mm_type == MAILMIME_MULTIPLE as libc::c_int { - let tp_type = unsafe { (*(*mime.mm_content_type).ct_type).tp_type }; - let ct_type = - unsafe { (*(*(*mime.mm_content_type).ct_type).tp_data.tp_composite_type).ct_type }; - - if tp_type == MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int - && ct_type == MAILMIME_COMPOSITE_TYPE_MULTIPART as libc::c_int - && to_string_lossy(unsafe { (*mime.mm_content_type).ct_subtype }) == "report" - { - return true; - } - - for cur_data in unsafe { (*(*mime.mm_mime_fields).fld_list).into_iter() } { - if contains_report(cur_data as *mut Mailmime) { - return true; - } - } - } else if mime.mm_type == MAILMIME_MESSAGE as libc::c_int { - let m = unsafe { mime.mm_data.mm_message.mm_msg_mime }; - - if contains_report(m) { - return true; - } - } - - false +fn contains_report(mail: &mailparse::ParsedMail<'_>) -> bool { + mail.ctype.mimetype == "multipart/report" } /// Ensures a private key exists for the configured user. @@ -699,7 +345,6 @@ pub fn ensure_secret_key_exists(context: &Context) -> Result { #[cfg(test)] mod tests { use super::*; - use libc::free; use crate::test_utils::*; @@ -722,7 +367,7 @@ mod tests { #[test] fn test_mailmime_parse() { - let plain = b"Chat-Disposition-Notification-To: holger@deltachat.de + let plain = b"Chat-Disposition-Notification-To: hello@world.de Chat-Group-ID: CovhGgau8M- Chat-Group-Name: Delta Chat Dev Subject: =?utf-8?Q?Chat=3A?= Delta Chat =?utf-8?Q?Dev=3A?= sidenote for @@ -730,35 +375,18 @@ Subject: =?utf-8?Q?Chat=3A?= Delta Chat =?utf-8?Q?Dev=3A?= sidenote for Content-Type: text/plain; charset=\"utf-8\"; protected-headers=\"v1\" Content-Transfer-Encoding: quoted-printable -sidenote for all: rust core master is broken currently ... so dont recomm= -end to try to run with desktop or ios unless you are ready to hunt bugs +sidenote for all: things are trick atm recomm= +end not to try to run with desktop or ios unless you are ready to hunt bugs -- =20 Sent with my Delta Chat Messenger: https://delta.chat"; - let plain_bytes = plain.len(); - let plain_buf = plain.as_ptr() as *const libc::c_char; + let mail = mailparse::parse_mail(plain).expect("failed to parse valid message"); - let mut index = 0; - let mut decrypted_mime = std::ptr::null_mut(); - - let res = unsafe { - mailmime_parse( - plain_buf as *const _, - plain_bytes, - &mut index, - &mut decrypted_mime, - ) - }; - unsafe { - let msg1 = (*decrypted_mime).mm_data.mm_message.mm_msg_mime; - let data = mailmime_transfer_decode(msg1).unwrap(); - println!("{:?}", String::from_utf8_lossy(&data)); - } - - assert_eq!(res, 0); - assert!(!decrypted_mime.is_null()); - - unsafe { free(decrypted_mime as *mut _) }; + assert_eq!(mail.headers.len(), 6); + assert!( + mail.get_body().unwrap().starts_with( + "sidenote for all: things are trick atm recommend not to try to run with desktop or ios unless you are ready to hunt bugs") + ); } mod load_or_generate_self_public_key { diff --git a/src/error.rs b/src/error.rs index b1e8419d5..588117f45 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,5 @@ use failure::Fail; +use lettre_email::mime; #[derive(Debug, Fail)] pub enum Error { @@ -14,8 +15,6 @@ pub enum Error { Image(image_meta::ImageError), #[fail(display = "{:?}", _0)] Utf8(std::str::Utf8Error), - #[fail(display = "{:?}", _0)] - CStringError(crate::dc_tools::CStringError), #[fail(display = "PGP: {:?}", _0)] Pgp(pgp::errors::Error), #[fail(display = "Base64Decode: {:?}", _0)] @@ -28,6 +27,12 @@ pub enum Error { InvalidMsgId, #[fail(display = "Watch folder not found {:?}", _0)] WatchFolderNotFound(String), + #[fail(display = "Inalid Email: {:?}", _0)] + MailParseError(#[cause] mailparse::MailParseError), + #[fail(display = "Building invalid Email: {:?}", _0)] + LettreError(#[cause] lettre_email::error::Error), + #[fail(display = "FromStr error: {:?}", _0)] + FromStr(#[cause] mime::FromStrError), } pub type Result = std::result::Result; @@ -68,12 +73,6 @@ impl From for Error { } } -impl From for Error { - fn from(err: crate::dc_tools::CStringError) -> Error { - Error::CStringError(err) - } -} - impl From for Error { fn from(err: pgp::errors::Error) -> Error { Error::Pgp(err) @@ -98,6 +97,24 @@ impl From for Error { } } +impl From for Error { + fn from(err: mailparse::MailParseError) -> Error { + Error::MailParseError(err) + } +} + +impl From for Error { + fn from(err: lettre_email::error::Error) -> Error { + Error::LettreError(err) + } +} + +impl From for Error { + fn from(err: mime::FromStrError) -> Error { + Error::FromStr(err) + } +} + #[macro_export] macro_rules! bail { ($e:expr) => { diff --git a/src/imap.rs b/src/imap.rs index 49f12b460..43f7d89cb 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -825,9 +825,7 @@ impl Imap { if !is_deleted && msg.body().is_some() { let body = msg.body().unwrap_or_default(); - unsafe { - dc_receive_imf(context, &body, folder.as_ref(), server_uid, flags as u32); - } + dc_receive_imf(context, &body, folder.as_ref(), server_uid, flags as u32); } } diff --git a/src/imex.rs b/src/imex.rs index 816db76f1..dc2e25965 100644 --- a/src/imex.rs +++ b/src/imex.rs @@ -12,7 +12,6 @@ use crate::config::Config; use crate::configure::*; use crate::constants::*; use crate::context::Context; -use crate::dc_mimeparser::SystemMessage; use crate::dc_tools::*; use crate::e2ee; use crate::error::*; @@ -20,6 +19,7 @@ use crate::events::Event; use crate::job::*; use crate::key::*; use crate::message::{Message, MsgId}; +use crate::mimeparser::SystemMessage; use crate::param::*; use crate::pgp; use crate::sql::{self, Sql}; diff --git a/src/job.rs b/src/job.rs index dd4e66561..6bdcba296 100644 --- a/src/job.rs +++ b/src/job.rs @@ -18,7 +18,7 @@ use crate::location; use crate::login_param::LoginParam; use crate::message::MsgId; use crate::message::{self, Message, MessageState}; -use crate::mimefactory::{vec_contains_lowercase, Loaded, MimeFactory}; +use crate::mimefactory::{vec_contains_lowercase, MimeFactory, RenderedEmail}; use crate::param::*; use crate::sql; @@ -604,22 +604,19 @@ fn set_delivered(context: &Context, msg_id: MsgId) { /* special case for DC_JOB_SEND_MSG_TO_SMTP */ #[allow(non_snake_case)] pub fn job_send_msg(context: &Context, msg_id: MsgId) -> Result<(), Error> { - let mut mimefactory = MimeFactory::load_msg(context, msg_id)?; - mimefactory.msg.try_calc_and_set_dimensions(context).ok(); + let mut msg = Message::load_from_db(context, msg_id)?; + msg.try_calc_and_set_dimensions(context).ok(); /* create message */ - if let Err(msg) = unsafe { mimefactory.render() } { - let e = msg.to_string(); - message::set_msg_failed(context, msg_id, Some(e)); - return Err(msg); - } - if 0 != mimefactory - .msg - .param - .get_int(Param::GuaranteeE2ee) - .unwrap_or_default() - && !mimefactory.out_encrypted - { + let needs_encryption = msg.param.get_int(Param::GuaranteeE2ee).unwrap_or_default(); + + let mimefactory = MimeFactory::from_msg(context, &msg)?; + let mut rendered_msg = mimefactory.render().map_err(|err| { + message::set_msg_failed(context, msg_id, Some(err.to_string())); + err + })?; + + if 0 != needs_encryption && !rendered_msg.is_encrypted { /* unrecoverable */ message::set_msg_failed( context, @@ -629,19 +626,17 @@ pub fn job_send_msg(context: &Context, msg_id: MsgId) -> Result<(), Error> { bail!( "e2e encryption unavailable {} - {:?}", msg_id, - mimefactory.msg.param.get_int(Param::GuaranteeE2ee), + needs_encryption ); } + if context.get_config_bool(Config::BccSelf) - && !vec_contains_lowercase(&mimefactory.recipients_addr, &mimefactory.from_addr) + && !vec_contains_lowercase(&rendered_msg.recipients, &rendered_msg.from) { - mimefactory.recipients_names.push("".to_string()); - mimefactory - .recipients_addr - .push(mimefactory.from_addr.to_string()); + rendered_msg.recipients.push(rendered_msg.from.clone()); } - if mimefactory.recipients_addr.is_empty() { + if rendered_msg.recipients.is_empty() { // may happen eg. for groups with only SELF and bcc_self disabled info!( context, @@ -651,36 +646,27 @@ pub fn job_send_msg(context: &Context, msg_id: MsgId) -> Result<(), Error> { return Ok(()); } - if mimefactory.out_gossiped { - chat::set_gossiped_timestamp(context, mimefactory.msg.chat_id, time()); + if rendered_msg.is_gossiped { + chat::set_gossiped_timestamp(context, msg.chat_id, time()); } - if 0 != mimefactory.out_last_added_location_id { - if let Err(err) = location::set_kml_sent_timestamp(context, mimefactory.msg.chat_id, time()) - { + if 0 != rendered_msg.last_added_location_id { + if let Err(err) = location::set_kml_sent_timestamp(context, msg.chat_id, time()) { error!(context, "Failed to set kml sent_timestamp: {:?}", err); } - if !mimefactory.msg.hidden { - if let Err(err) = location::set_msg_location_id( - context, - mimefactory.msg.id, - mimefactory.out_last_added_location_id, - ) { + if !msg.hidden { + if let Err(err) = + location::set_msg_location_id(context, msg.id, rendered_msg.last_added_location_id) + { error!(context, "Failed to set msg_location_id: {:?}", err); } } } - if mimefactory.out_encrypted - && mimefactory - .msg - .param - .get_int(Param::GuaranteeE2ee) - .unwrap_or_default() - == 0 - { - mimefactory.msg.param.set_int(Param::GuaranteeE2ee, 1); - mimefactory.msg.save_param_to_disk(context); + if rendered_msg.is_encrypted && needs_encryption == 0 { + msg.param.set_int(Param::GuaranteeE2ee, 1); + msg.save_param_to_disk(context); } - add_smtp_job(context, Action::SendMsgToSmtp, &mut mimefactory)?; + + add_smtp_job(context, Action::SendMsgToSmtp, &rendered_msg)?; Ok(()) } @@ -866,38 +852,40 @@ fn suspend_smtp_thread(context: &Context, suspend: bool) { } fn send_mdn(context: &Context, msg_id: MsgId) -> Result<(), Error> { - let mut mimefactory = MimeFactory::load_mdn(context, msg_id)?; - unsafe { mimefactory.render()? }; - add_smtp_job(context, Action::SendMdn, &mut mimefactory)?; + let msg = Message::load_from_db(context, msg_id)?; + let mimefactory = MimeFactory::from_mdn(context, &msg)?; + let rendered_msg = mimefactory.render()?; + + add_smtp_job(context, Action::SendMdn, &rendered_msg)?; Ok(()) } #[allow(non_snake_case)] -fn add_smtp_job(context: &Context, action: Action, mimefactory: &MimeFactory) -> Result<(), Error> { +fn add_smtp_job( + context: &Context, + action: Action, + rendered_msg: &RenderedEmail, +) -> Result<(), Error> { ensure!( - !mimefactory.recipients_addr.is_empty(), + !rendered_msg.recipients.is_empty(), "no recipients for smtp job set" ); let mut param = Params::new(); - let bytes = unsafe { - std::slice::from_raw_parts( - (*mimefactory.out).str_0 as *const u8, - (*mimefactory.out).len, - ) - }; - let blob = BlobObject::create(context, &mimefactory.rfc724_mid, bytes)?; - let recipients = mimefactory.recipients_addr.join("\x1e"); + let bytes = &rendered_msg.message; + let blob = BlobObject::create(context, &rendered_msg.rfc724_mid, bytes)?; + + let recipients = rendered_msg.recipients.join("\x1e"); param.set(Param::File, blob.as_name()); param.set(Param::Recipients, &recipients); + job_add( context, action, - (if mimefactory.loaded == Loaded::Message { - mimefactory.msg.id.to_u32() as i32 - } else { - 0 - }) as libc::c_int, + rendered_msg + .foreign_id + .map(|v| v.to_u32() as i32) + .unwrap_or_default(), param, 0, ); @@ -908,7 +896,7 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &MimeFactory) -> pub fn job_add( context: &Context, action: Action, - foreign_id: libc::c_int, + foreign_id: i32, param: Params, delay_seconds: i64, ) { diff --git a/src/lib.rs b/src/lib.rs index 64c39353a..698edee37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,8 +17,6 @@ extern crate strum; #[macro_use] extern crate strum_macros; #[macro_use] -extern crate jetscii; -#[macro_use] extern crate debug_stub_derive; #[macro_use] @@ -51,6 +49,7 @@ mod login_param; pub mod lot; pub mod message; mod mimefactory; +pub mod mimeparser; pub mod oauth2; mod param; pub mod peerstate; @@ -63,14 +62,13 @@ pub mod stock; mod token; #[macro_use] mod wrapmime; +mod dehtml; pub mod dc_array; -pub mod dc_mimeparser; pub mod dc_receive_imf; mod dc_simplify; mod dc_strencode; pub mod dc_tools; -mod dehtml; #[cfg(test)] mod test_utils; diff --git a/src/location.rs b/src/location.rs index f9375b0cd..35bee16da 100644 --- a/src/location.rs +++ b/src/location.rs @@ -8,12 +8,12 @@ use crate::chat; use crate::config::Config; use crate::constants::*; use crate::context::*; -use crate::dc_mimeparser::SystemMessage; use crate::dc_tools::*; use crate::error::Error; use crate::events::Event; use crate::job::*; use crate::message::{Message, MsgId}; +use crate::mimeparser::SystemMessage; use crate::param::*; use crate::sql; use crate::stock::StockMessage; @@ -229,7 +229,7 @@ pub fn send_locations_to_chat(context: &Context, chat_id: u32, seconds: i64) { job_add( context, Action::MaybeSendLocationsEnded, - chat_id as libc::c_int, + chat_id as i32, Params::new(), seconds + 1, ); diff --git a/src/message.rs b/src/message.rs index dccb500ac..bf1cb1d97 100644 --- a/src/message.rs +++ b/src/message.rs @@ -7,12 +7,12 @@ use crate::chat::{self, Chat}; use crate::constants::*; use crate::contact::*; use crate::context::*; -use crate::dc_mimeparser::SystemMessage; use crate::dc_tools::*; use crate::error::Error; use crate::events::Event; use crate::job::*; use crate::lot::{Lot, LotState, Meaning}; +use crate::mimeparser::SystemMessage; use crate::param::*; use crate::pgp::*; use crate::sql; @@ -457,8 +457,8 @@ impl Message { return ret; }; - let contact = if self.from_id != DC_CONTACT_ID_SELF as libc::c_uint - && ((*chat).typ == Chattype::Group || (*chat).typ == Chattype::VerifiedGroup) + let contact = if self.from_id != DC_CONTACT_ID_SELF as u32 + && (chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup) { Contact::get_by_id(context, self.from_id).ok() } else { @@ -470,11 +470,11 @@ impl Message { ret } - pub fn get_summarytext(&mut self, context: &Context, approx_characters: usize) -> String { + pub fn get_summarytext(&self, context: &Context, approx_characters: usize) -> String { get_summarytext_by_raw( self.type_0, self.text.as_ref(), - &mut self.param, + &self.param, approx_characters, context, ) @@ -502,8 +502,8 @@ impl Message { pub fn is_info(&self) -> bool { let cmd = self.param.get_cmd(); - self.from_id == DC_CONTACT_ID_INFO as libc::c_uint - || self.to_id == DC_CONTACT_ID_INFO as libc::c_uint + self.from_id == DC_CONTACT_ID_INFO as u32 + || self.to_id == DC_CONTACT_ID_INFO as u32 || cmd != SystemMessage::Unknown && cmd != SystemMessage::AutocryptSetupMessage } @@ -730,7 +730,7 @@ pub fn get_msg_info(context: &Context, msg_id: MsgId) -> String { ret += &format!(" by {}", name); ret += "\n"; - if msg.from_id != DC_CONTACT_ID_SELF as libc::c_uint { + if msg.from_id != DC_CONTACT_ID_SELF as u32 { let s = dc_timestamp_to_str(if 0 != msg.timestamp_rcvd { msg.timestamp_rcvd } else { @@ -1013,7 +1013,7 @@ pub fn star_msgs(context: &Context, msg_ids: &[MsgId], star: bool) -> bool { pub fn get_summarytext_by_raw( viewtype: Viewtype, text: Option>, - param: &mut Params, + param: &Params, approx_characters: usize, context: &Context, ) -> String { @@ -1137,7 +1137,7 @@ pub fn mdn_from_ext( return None; } - if let Ok((msg_id, chat_id, chat_type, msg_state)) = context.sql.query_row( + let res = context.sql.query_row( concat!( "SELECT", " m.id AS msg_id,", @@ -1157,7 +1157,12 @@ pub fn mdn_from_ext( row.get::<_, MessageState>("state")?, )) }, - ) { + ); + if let Err(ref err) = res { + info!(context, "Failed to select MDN {:?}", err); + } + + if let Ok((msg_id, chat_id, chat_type, msg_state)) = res { let mut read_by_all = false; // if already marked as MDNS_RCVD msgstate_can_fail() returns false. @@ -1222,7 +1227,7 @@ pub fn mdn_from_ext( } /// The number of messages assigned to real chat (!=deaddrop, !=trash) -pub fn get_real_msg_cnt(context: &Context) -> libc::c_int { +pub fn get_real_msg_cnt(context: &Context) -> i32 { match context.sql.query_row( "SELECT COUNT(*) \ FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id \ @@ -1238,7 +1243,7 @@ pub fn get_real_msg_cnt(context: &Context) -> libc::c_int { } } -pub fn get_deaddrop_msg_cnt(context: &Context) -> libc::size_t { +pub fn get_deaddrop_msg_cnt(context: &Context) -> usize { match context.sql.query_row( "SELECT COUNT(*) \ FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id \ @@ -1246,7 +1251,7 @@ pub fn get_deaddrop_msg_cnt(context: &Context) -> libc::size_t { rusqlite::NO_PARAMS, |row| row.get::<_, isize>(0), ) { - Ok(res) => res as libc::size_t, + Ok(res) => res as usize, Err(err) => { error!(context, "dc_get_deaddrop_msg_cnt() failed. {}", err); 0 @@ -1254,7 +1259,7 @@ pub fn get_deaddrop_msg_cnt(context: &Context) -> libc::size_t { } } -pub fn rfc724_mid_cnt(context: &Context, rfc724_mid: &str) -> libc::c_int { +pub fn rfc724_mid_cnt(context: &Context, rfc724_mid: &str) -> i32 { // check the number of messages with the same rfc724_mid match context.sql.query_row( "SELECT COUNT(*) FROM msgs WHERE rfc724_mid=?;", diff --git a/src/mimefactory.rs b/src/mimefactory.rs index cf56c42f8..113475f1e 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -1,22 +1,11 @@ -use std::ptr; - use chrono::TimeZone; -use mmime::clist::*; -use mmime::mailimf::types::*; -use mmime::mailimf::types_helper::*; -use mmime::mailmime::disposition::*; -use mmime::mailmime::types::*; -use mmime::mailmime::types_helper::*; -use mmime::mailmime::write_mem::*; -use mmime::mmapstring::*; -use mmime::other::*; +use lettre_email::{mime, Address, Header, MimeMultipartType, PartBuilder}; use crate::chat::{self, Chat}; use crate::config::Config; use crate::constants::*; use crate::contact::*; use crate::context::{get_version_str, Context}; -use crate::dc_mimeparser::SystemMessage; use crate::dc_strencode::*; use crate::dc_tools::*; use crate::e2ee::*; @@ -24,43 +13,60 @@ use crate::error::Error; use crate::location; use crate::message::MsgId; use crate::message::{self, Message}; +use crate::mimeparser::SystemMessage; use crate::param::*; +use crate::peerstate::{Peerstate, PeerstateVerifiedStatus}; use crate::stock::StockMessage; -use crate::wrapmime; #[derive(Clone, Copy, Eq, PartialEq)] pub enum Loaded { - Nothing, Message, - MDN, // TODO: invent more descriptive name + MDN, } +/// Helper to construct mime messages. #[derive(Clone)] -pub struct MimeFactory<'a> { +pub struct MimeFactory<'a, 'b> { pub from_addr: String, pub from_displayname: String, pub selfstatus: String, pub recipients_names: Vec, pub recipients_addr: Vec, pub timestamp: i64, - pub rfc724_mid: String, pub loaded: Loaded, - pub msg: Message, + pub msg: &'b Message, pub chat: Option, pub increation: bool, pub in_reply_to: String, pub references: String, pub req_mdn: bool, - pub out: *mut MMAPString, - pub out_encrypted: bool, - pub out_gossiped: bool, - pub out_last_added_location_id: u32, pub context: &'a Context, + last_added_location_id: u32, } -impl<'a> MimeFactory<'a> { - fn new(context: &'a Context, msg: Message) -> Self { - MimeFactory { +/// Result of rendering a message, ready to be submitted to a send job. +#[derive(Debug, Clone)] +pub struct RenderedEmail { + pub message: Vec, + // pub envelope: Envelope, + pub is_encrypted: bool, + pub is_gossiped: bool, + pub last_added_location_id: u32, + /// None for MDN, the message id otherwise + pub foreign_id: Option, + + pub from: String, + pub recipients: Vec, + + /// Message ID (Message in the sense of Email) + pub rfc724_mid: String, +} + +impl<'a, 'b> MimeFactory<'a, 'b> { + pub fn from_msg(context: &'a Context, msg: &'b Message) -> Result, Error> { + let chat = Chat::load_from_db(context, msg.chat_id)?; + + let mut factory = MimeFactory { from_addr: context .get_config(Config::ConfiguredAddr) .unwrap_or_default(), @@ -70,599 +76,17 @@ impl<'a> MimeFactory<'a> { .unwrap_or_else(|| context.stock_str(StockMessage::StatusLine).to_string()), recipients_names: Vec::with_capacity(5), recipients_addr: Vec::with_capacity(5), - timestamp: 0, - rfc724_mid: String::default(), - loaded: Loaded::Nothing, + timestamp: msg.timestamp_sort, + loaded: Loaded::Message, msg, - chat: None, - increation: false, + chat: Some(chat), + increation: msg.is_increation(), in_reply_to: String::default(), references: String::default(), req_mdn: false, - out: ptr::null_mut(), - out_encrypted: false, - out_gossiped: false, - out_last_added_location_id: 0, + last_added_location_id: 0, context, - } - } - - pub fn finalize_mime_message( - &mut self, - message: *mut Mailmime, - encrypted: bool, - gossiped: bool, - ) -> Result<(), Error> { - unsafe { - assert!(self.out.is_null()); // guard against double-calls - self.out = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char); - let mut col: libc::c_int = 0; - ensure_eq!( - mailmime_write_mem(self.out, &mut col, message), - 0, - "mem-error" - ); - } - self.out_encrypted = encrypted; - self.out_gossiped = encrypted && gossiped; - Ok(()) - } - - pub fn load_mdn(context: &'a Context, msg_id: MsgId) -> Result { - if !context.get_config_bool(Config::MdnsEnabled) { - // MDNs not enabled - check this is late, in the job. the - // user may have changed its choice while offline ... - bail!("MDNs meanwhile disabled") - } - - let msg = Message::load_from_db(context, msg_id)?; - let mut factory = MimeFactory::new(context, msg); - let contact = Contact::load_from_db(factory.context, factory.msg.from_id)?; - - // Do not send MDNs trash etc.; chats.blocked is already checked by the caller - // in dc_markseen_msgs() - ensure!(!contact.is_blocked(), "Contact blocked"); - ensure!( - factory.msg.chat_id > DC_CHAT_ID_LAST_SPECIAL, - "Invalid chat id" - ); - - factory - .recipients_names - .push(contact.get_authname().to_string()); - factory.recipients_addr.push(contact.get_addr().to_string()); - factory.timestamp = dc_create_smeared_timestamp(factory.context); - factory.rfc724_mid = dc_create_outgoing_rfc724_mid(None, &factory.from_addr); - factory.loaded = Loaded::MDN; - - Ok(factory) - } - - /******************************************************************************* - * Render a basic email - ******************************************************************************/ - // XXX restrict unsafe to parts, introduce wrapmime helpers where appropriate - pub unsafe fn render(&mut self) -> Result<(), Error> { - if self.loaded == Loaded::Nothing || !self.out.is_null() { - bail!("Invalid use of mimefactory-object."); - } - let context = &self.context; - let from = wrapmime::new_mailbox_list(&self.from_displayname, &self.from_addr); - - let to = mailimf_address_list_new_empty(); - let name_iter = self.recipients_names.iter(); - let addr_iter = self.recipients_addr.iter(); - for (name, addr) in name_iter.zip(addr_iter) { - mailimf_address_list_add( - to, - mailimf_address_new( - MAILIMF_ADDRESS_MAILBOX as libc::c_int, - mailimf_mailbox_new( - if !name.is_empty() { - dc_encode_header_words(&name).strdup() - } else { - ptr::null_mut() - }, - addr.strdup(), - ), - ptr::null_mut(), - ), - ); - } - let references_list = if !self.references.is_empty() { - dc_str_to_clist(&self.references, " ") - } else { - ptr::null_mut() }; - let in_reply_to_list = if !self.in_reply_to.is_empty() { - dc_str_to_clist(&self.in_reply_to, " ") - } else { - ptr::null_mut() - }; - - let imf_fields = mailimf_fields_new_with_data_all( - mailimf_get_date(self.timestamp as i64), - from, - ptr::null_mut(), - ptr::null_mut(), - to, - ptr::null_mut(), - ptr::null_mut(), - self.rfc724_mid.strdup(), - in_reply_to_list, - references_list, - ptr::null_mut(), - ); - - let os_name = &self.context.os_name; - let os_part = os_name - .as_ref() - .map(|s| format!("/{}", s)) - .unwrap_or_default(); - let version = get_version_str(); - let headerval = format!("Delta Chat Core {}{}", version, os_part); - - /* Add a X-Mailer header. - This is only informational for debugging and may be removed in the release. - We do not rely on this header as it may be removed by MTAs. */ - wrapmime::new_custom_field(imf_fields, "X-Mailer", &headerval); - wrapmime::new_custom_field(imf_fields, "Chat-Version", "1.0"); - if self.req_mdn { - /* we use "Chat-Disposition-Notification-To" - because replies to "Disposition-Notification-To" are weird in many cases - eg. are just freetext and/or do not follow any standard. */ - wrapmime::new_custom_field( - imf_fields, - "Chat-Disposition-Notification-To", - &self.from_addr, - ); - } - - let cleanup = |message: *mut Mailmime| { - if !message.is_null() { - mailmime_free(message); - } - }; - let message = mailmime_new_message_data(0 as *mut Mailmime); - ensure!(!message.is_null(), "could not create mime message data"); - - mailmime_set_imf_fields(message, imf_fields); - - // 1=add Autocrypt-header (needed eg. for handshaking), 2=no Autocrypte-header (used for MDN) - let mut e2ee_guaranteed = false; - let mut min_verified = crate::peerstate::PeerstateVerifiedStatus::Unverified; - let mut do_gossip = false; - let mut grpimage = None; - let force_plaintext: libc::c_int; - let subject_str = match self.loaded { - Loaded::Message => { - /* Render a normal message - *********************************************************************/ - let chat = self.chat.as_ref().unwrap(); - let mut meta_part: *mut Mailmime = ptr::null_mut(); - let mut placeholdertext = None; - - if chat.typ == Chattype::VerifiedGroup { - wrapmime::new_custom_field(imf_fields, "Chat-Verified", "1"); - force_plaintext = 0; - e2ee_guaranteed = true; - min_verified = crate::peerstate::PeerstateVerifiedStatus::BidirectVerified; - } else { - force_plaintext = self - .msg - .param - .get_int(Param::ForcePlaintext) - .unwrap_or_default(); - if force_plaintext == 0 { - e2ee_guaranteed = self - .msg - .param - .get_int(Param::GuaranteeE2ee) - .unwrap_or_default() - != 0; - } - } - - /* beside key- and member-changes, force re-gossip every 48 hours */ - if chat.gossiped_timestamp == 0 - || (chat.gossiped_timestamp + (2 * 24 * 60 * 60)) < time() - { - do_gossip = true - } - - /* build header etc. */ - let command = self.msg.param.get_cmd(); - if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup { - wrapmime::new_custom_field(imf_fields, "Chat-Group-ID", &chat.grpid); - - let encoded = dc_encode_header_words(&chat.name); - wrapmime::new_custom_field(imf_fields, "Chat-Group-Name", &encoded); - - match command { - SystemMessage::MemberRemovedFromGroup => { - let email_to_remove = - self.msg.param.get(Param::Arg).unwrap_or_default(); - if !email_to_remove.is_empty() { - wrapmime::new_custom_field( - imf_fields, - "Chat-Group-Member-Removed", - &email_to_remove, - ); - } - } - SystemMessage::MemberAddedToGroup => { - let msg = &self.msg; - do_gossip = true; - let email_to_add = msg.param.get(Param::Arg).unwrap_or_default(); - if !email_to_add.is_empty() { - wrapmime::new_custom_field( - imf_fields, - "Chat-Group-Member-Added", - &email_to_add, - ); - grpimage = chat.param.get(Param::ProfileImage); - } - if 0 != msg.param.get_int(Param::Arg2).unwrap_or_default() & 0x1 { - info!( - context, - "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", - "vg-member-added", - ); - wrapmime::new_custom_field( - imf_fields, - "Secure-Join", - "vg-member-added", - ); - } - } - SystemMessage::GroupNameChanged => { - let msg = &self.msg; - let value_to_add = msg.param.get(Param::Arg).unwrap_or_default(); - - wrapmime::new_custom_field( - imf_fields, - "Chat-Group-Name-Changed", - &value_to_add, - ); - } - SystemMessage::GroupImageChanged => { - let msg = &self.msg; - grpimage = msg.param.get(Param::Arg); - if grpimage.is_none() { - wrapmime::new_custom_field(imf_fields, "Chat-Group-Image", "0"); - } - } - _ => {} - } - } - - match command { - SystemMessage::LocationStreamingEnabled => { - wrapmime::new_custom_field( - imf_fields, - "Chat-Content", - "location-streaming-enabled", - ); - } - SystemMessage::AutocryptSetupMessage => { - wrapmime::new_custom_field(imf_fields, "Autocrypt-Setup-Message", "v1"); - placeholdertext = Some( - self.context - .stock_str(StockMessage::AcSetupMsgBody) - .to_string(), - ); - } - SystemMessage::SecurejoinMessage => { - let msg = &self.msg; - let step = msg.param.get(Param::Arg).unwrap_or_default(); - if !step.is_empty() { - info!( - context, - "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", - step, - ); - wrapmime::new_custom_field(imf_fields, "Secure-Join", &step); - let param2 = msg.param.get(Param::Arg2).unwrap_or_default(); - if !param2.is_empty() { - wrapmime::new_custom_field( - imf_fields, - if step == "vg-request-with-auth" - || step == "vc-request-with-auth" - { - "Secure-Join-Auth" - } else { - "Secure-Join-Invitenumber" - }, - param2, - ) - } - let fingerprint = msg.param.get(Param::Arg3).unwrap_or_default(); - if !fingerprint.is_empty() { - wrapmime::new_custom_field( - imf_fields, - "Secure-Join-Fingerprint", - &fingerprint, - ); - } - if let Some(id) = msg.param.get(Param::Arg4) { - wrapmime::new_custom_field(imf_fields, "Secure-Join-Group", &id); - }; - } - } - _ => {} - } - - if let Some(grpimage) = grpimage { - info!(self.context, "setting group image '{}'", grpimage); - let mut meta = Message::default(); - meta.type_0 = Viewtype::Image; - meta.param.set(Param::File, grpimage); - - let res = build_body_file(context, &meta, "group-image")?; - meta_part = res.0; - let filename_as_sent = res.1; - if !meta_part.is_null() { - wrapmime::new_custom_field( - imf_fields, - "Chat-Group-Image", - &filename_as_sent, - ) - } - } - - if self.msg.type_0 == Viewtype::Sticker { - wrapmime::new_custom_field(imf_fields, "Chat-Content", "sticker"); - } - - if self.msg.type_0 == Viewtype::Voice - || self.msg.type_0 == Viewtype::Audio - || self.msg.type_0 == Viewtype::Video - { - if self.msg.type_0 == Viewtype::Voice { - wrapmime::new_custom_field(imf_fields, "Chat-Voice-Message", "1"); - } - let duration_ms = self.msg.param.get_int(Param::Duration).unwrap_or_default(); - if duration_ms > 0 { - let dur = duration_ms.to_string(); - wrapmime::new_custom_field(imf_fields, "Chat-Duration", &dur); - } - } - - /* add text part - we even add empty text and force a MIME-multipart-message as: - - some Apps have problems with Non-text in the main part (eg. "Mail" from stock Android) - - we can add "forward hints" this way - - it looks better */ - let afwd_email = self.msg.param.exists(Param::Forwarded); - let fwdhint = if afwd_email { - Some( - "---------- Forwarded message ----------\r\nFrom: Delta Chat\r\n\r\n" - .to_string(), - ) - } else { - None - }; - - let final_text = { - if let Some(ref text) = placeholdertext { - text - } else if let Some(ref text) = self.msg.text { - text - } else { - "" - } - }; - - let footer = &self.selfstatus; - let message_text = format!( - "{}{}{}{}{}", - fwdhint.unwrap_or_default(), - &final_text, - if !final_text.is_empty() && !footer.is_empty() { - "\r\n\r\n" - } else { - "" - }, - if !footer.is_empty() { "-- \r\n" } else { "" }, - footer - ); - let text_part = wrapmime::build_body_text(&message_text)?; - mailmime_smart_add_part(message, text_part); - - /* add attachment part */ - if chat::msgtype_has_file(self.msg.type_0) { - if !is_file_size_okay(context, &self.msg) { - cleanup(message); - bail!( - "Message exceeds the recommended {} MB.", - 24 * 1024 * 1024 / 4 * 3 / 1000 / 1000, - ); - } else { - let (file_part, _) = build_body_file(context, &self.msg, "")?; - mailmime_smart_add_part(message, file_part); - } - } - if !meta_part.is_null() { - mailmime_smart_add_part(message, meta_part); - } - - if self.msg.param.exists(Param::SetLatitude) { - let param = &self.msg.param; - let kml_file = location::get_message_kml( - self.msg.timestamp_sort, - param.get_float(Param::SetLatitude).unwrap_or_default(), - param.get_float(Param::SetLongitude).unwrap_or_default(), - ); - wrapmime::add_filename_part( - message, - "message.kml", - "application/vnd.google-earth.kml+xml", - &kml_file, - )?; - } - - if location::is_sending_locations_to_chat(context, self.msg.chat_id) { - match location::get_kml(context, self.msg.chat_id) { - Ok((kml_content, last_added_location_id)) => { - wrapmime::add_filename_part( - message, - "location.kml", - "application/vnd.google-earth.kml+xml", - &kml_content, - )?; - if !self.msg.param.exists(Param::SetLatitude) { - // otherwise, the independent location is already filed - self.out_last_added_location_id = last_added_location_id; - } - } - Err(err) => { - warn!(context, "mimefactory: could not get location: {}", err); - } - } - } - get_subject(context, self.chat.as_ref(), &mut self.msg, afwd_email) - } - Loaded::MDN => { - /* Render a MDN - *********************************************************************/ - /* RFC 6522, this also requires the `report-type` parameter which is equal - to the MIME subtype of the second body part of the multipart/report */ - let multipart = mailmime_multiple_new( - b"multipart/report\x00" as *const u8 as *const libc::c_char, - ); - wrapmime::append_ct_param( - (*multipart).mm_content_type, - "report-type", - "disposition-notification", - )?; - - mailmime_add_part(message, multipart); - - /* first body part: always human-readable, always REQUIRED by RFC 6522 */ - let p1 = if 0 - != self - .msg - .param - .get_int(Param::GuaranteeE2ee) - .unwrap_or_default() - { - self.context - .stock_str(StockMessage::EncryptedMsg) - .into_owned() - } else { - self.msg.get_summarytext(context, 32) - }; - let p2 = self - .context - .stock_string_repl_str(StockMessage::ReadRcptMailBody, p1); - let message_text = format!("{}\r\n", p2); - let human_mime_part = wrapmime::build_body_text(&message_text)?; - mailmime_add_part(multipart, human_mime_part); - - /* second body part: machine-readable, always REQUIRED by RFC 6522 */ - let version = get_version_str(); - let message_text2 = format!( - "Reporting-UA: Delta Chat {}\r\nOriginal-Recipient: rfc822;{}\r\nFinal-Recipient: rfc822;{}\r\nOriginal-Message-ID: <{}>\r\nDisposition: manual-action/MDN-sent-automatically; displayed\r\n", - version, - self.from_addr, - self.from_addr, - self.msg.rfc724_mid - ); - - let content_type_0 = - wrapmime::new_content_type("message/disposition-notification")?; - let mime_fields_0: *mut mailmime_fields = - mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT as libc::c_int); - let mach_mime_part: *mut Mailmime = - mailmime_new_empty(content_type_0, mime_fields_0); - wrapmime::set_body_text(mach_mime_part, &message_text2)?; - mailmime_add_part(multipart, mach_mime_part); - force_plaintext = DC_FP_NO_AUTOCRYPT_HEADER; - /* currently, we do not send MDNs encrypted: - - in a multi-device-setup that is not set up properly, MDNs would disturb the communication as they - are send automatically which may lead to spreading outdated Autocrypt headers. - - they do not carry any information but the Message-ID - - this save some KB - - in older versions, we did not encrypt messages to ourself when they to to SMTP - however, if these messages - are forwarded for any reasons (eg. gmail always forwards to IMAP), we have no chance to decrypt them; - this issue is fixed with 0.9.4 */ - let e = self.context.stock_str(StockMessage::ReadRcpt); - format!("Chat: {}", e).to_string() - } - _ => { - cleanup(message); - bail!("No message loaded."); - } - }; - - /* Create the mime message - *************************************************************************/ - - mailimf_fields_add( - imf_fields, - mailimf_field_new( - MAILIMF_FIELD_SUBJECT as libc::c_int, - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - mailimf_subject_new(dc_encode_header_words(subject_str).strdup()), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ), - ); - - /*just a pointer into mailmime structure, must not be freed*/ - let imffields_unprotected = wrapmime::mailmime_find_mailimf_fields(message); - ensure!( - !imffields_unprotected.is_null(), - "could not find mime fields" - ); - - let mut encrypt_helper = EncryptHelper::new(&context)?; - if force_plaintext != DC_FP_NO_AUTOCRYPT_HEADER { - // unless determined otherwise we add Autocrypt header - let aheader = encrypt_helper.get_aheader().to_string(); - wrapmime::new_custom_field(imffields_unprotected, "Autocrypt", &aheader); - } - let finalized = if force_plaintext == 0 { - encrypt_helper.try_encrypt( - self, - e2ee_guaranteed, - min_verified, - do_gossip, - message, - imffields_unprotected, - )? - } else { - false - }; - if !finalized { - self.finalize_mime_message(message, false, false)?; - } - cleanup(message); - Ok(()) - } - - pub fn load_msg(context: &Context, msg_id: MsgId) -> Result { - let msg = Message::load_from_db(context, msg_id)?; - let chat = Chat::load_from_db(context, msg.chat_id)?; - let mut factory = MimeFactory::new(context, msg); - factory.chat = Some(chat); // just set the chat above let chat = factory.chat.as_ref().unwrap(); @@ -723,7 +147,7 @@ impl<'a> MimeFactory<'a> { } let row = context.sql.query_row( "SELECT mime_in_reply_to, mime_references FROM msgs WHERE id=?", - params![factory.msg.id], + params![msg.id], |row| { let in_reply_to: String = row.get(0)?; let references: String = row.get(1)?; @@ -731,6 +155,7 @@ impl<'a> MimeFactory<'a> { Ok((in_reply_to, references)) }, ); + match row { Ok((in_reply_to, references)) => { factory.in_reply_to = in_reply_to; @@ -744,58 +169,776 @@ impl<'a> MimeFactory<'a> { } } - factory.loaded = Loaded::Message; - factory.timestamp = factory.msg.timestamp_sort; - factory.rfc724_mid = factory.msg.rfc724_mid.clone(); - factory.increation = factory.msg.is_increation(); - Ok(factory) } -} -impl<'a> Drop for MimeFactory<'a> { - fn drop(&mut self) { - unsafe { - if !self.out.is_null() { - mmap_string_free(self.out); + pub fn from_mdn(context: &'a Context, msg: &'b Message) -> Result { + // MDNs not enabled - check this is late, in the job. the + // user may have changed its choice while offline ... + ensure!( + context.get_config_bool(Config::MdnsEnabled), + "MDNs meanwhile disabled" + ); + + let contact = Contact::load_from_db(context, msg.from_id)?; + + // Do not send MDNs trash etc.; chats.blocked is already checked by the caller + // in dc_markseen_msgs() + ensure!(!contact.is_blocked(), "Contact blocked"); + ensure!(msg.chat_id > DC_CHAT_ID_LAST_SPECIAL, "Invalid chat id"); + + Ok(MimeFactory { + context, + from_addr: context + .get_config(Config::ConfiguredAddr) + .unwrap_or_default(), + from_displayname: context.get_config(Config::Displayname).unwrap_or_default(), + selfstatus: context + .get_config(Config::Selfstatus) + .unwrap_or_else(|| context.stock_str(StockMessage::StatusLine).to_string()), + recipients_names: vec![contact.get_authname().to_string()], + recipients_addr: vec![contact.get_addr().to_string()], + timestamp: dc_create_smeared_timestamp(context), + loaded: Loaded::MDN, + msg, + chat: None, + increation: false, + in_reply_to: String::default(), + references: String::default(), + req_mdn: false, + last_added_location_id: 0, + }) + } + + fn peerstates_for_recipients(&self) -> Result, &str)>, Error> { + let self_addr = self + .context + .get_config(Config::ConfiguredAddr) + .ok_or_else(|| format_err!("Not configured"))?; + + Ok(self + .recipients_addr + .iter() + .filter(|addr| *addr != &self_addr) + .map(|addr| { + ( + Peerstate::from_addr(self.context, &self.context.sql, addr), + addr.as_str(), + ) + }) + .collect()) + } + + fn is_e2ee_guranteed(&self) -> bool { + match self.loaded { + Loaded::Message => { + if self.chat.as_ref().unwrap().typ == Chattype::VerifiedGroup { + return true; + } + + let force_plaintext = self + .msg + .param + .get_int(Param::ForcePlaintext) + .unwrap_or_default(); + + if force_plaintext == 0 { + return self + .msg + .param + .get_int(Param::GuaranteeE2ee) + .unwrap_or_default() + != 0; + } + + false + } + Loaded::MDN => false, + } + } + + fn min_verified(&self) -> PeerstateVerifiedStatus { + match self.loaded { + Loaded::Message => { + let chat = self.chat.as_ref().unwrap(); + if chat.typ == Chattype::VerifiedGroup { + PeerstateVerifiedStatus::BidirectVerified + } else { + PeerstateVerifiedStatus::Unverified + } + } + Loaded::MDN => PeerstateVerifiedStatus::Unverified, + } + } + + fn should_force_plaintext(&self) -> i32 { + match self.loaded { + Loaded::Message => { + let chat = self.chat.as_ref().unwrap(); + if chat.typ == Chattype::VerifiedGroup { + 0 + } else { + self.msg + .param + .get_int(Param::ForcePlaintext) + .unwrap_or_default() + } + } + Loaded::MDN => DC_FP_NO_AUTOCRYPT_HEADER, + } + } + + fn should_do_gossip(&self) -> bool { + match self.loaded { + Loaded::Message => { + let chat = self.chat.as_ref().unwrap(); + // beside key- and member-changes, force re-gossip every 48 hours + if chat.gossiped_timestamp == 0 + || (chat.gossiped_timestamp + (2 * 24 * 60 * 60)) > time() + { + return true; + } + + match self.msg.param.get_cmd() { + SystemMessage::MemberAddedToGroup => { + return true; + } + _ => {} + } + + false + } + Loaded::MDN => false, + } + } + + fn grpimage(&self) -> Option { + match self.loaded { + Loaded::Message => { + let chat = self.chat.as_ref().unwrap(); + let cmd = self.msg.param.get_cmd(); + + match cmd { + SystemMessage::MemberAddedToGroup => { + return chat.param.get(Param::ProfileImage).map(Into::into); + } + SystemMessage::GroupImageChanged => { + return self.msg.param.get(Param::Arg).map(Into::into) + } + _ => {} + } + + None + } + Loaded::MDN => None, + } + } + + fn subject_str(&self) -> String { + match self.loaded { + Loaded::Message => { + match self.chat { + Some(ref chat) => { + let raw_subject = message::get_summarytext_by_raw( + self.msg.type_0, + self.msg.text.as_ref(), + &self.msg.param, + 32, + self.context, + ); + + let afwd_email = self.msg.param.exists(Param::Forwarded); + let fwd = if afwd_email { "Fwd: " } else { "" }; + + if self.msg.param.get_cmd() == SystemMessage::AutocryptSetupMessage { + // do not add the "Chat:" prefix for setup messages + self.context + .stock_str(StockMessage::AcSetupMsgSubject) + .into_owned() + } else if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup + { + format!("Chat: {}: {}{}", chat.name, fwd, raw_subject) + } else { + format!("Chat: {}{}", fwd, raw_subject) + } + } + None => String::new(), + } + } + Loaded::MDN => { + let e = self.context.stock_str(StockMessage::ReadRcpt); + format!("Chat: {}", e) } } } -} -fn get_subject( - context: &Context, - chat: Option<&Chat>, - msg: &mut Message, - afwd_email: bool, -) -> String { - if chat.is_none() { - return String::default(); + pub fn render(mut self) -> Result { + // Headers that are encrypted + // - Chat-*, except Chat-Version + // - Secure-Join* + // - Subject + let mut protected_headers: Vec
= Vec::new(); + + // All other headers + let mut unprotected_headers: Vec
= Vec::new(); + + let from = Address::new_mailbox_with_name( + dc_encode_header_words(&self.from_displayname), + self.from_addr.clone(), + ); + + let mut to = Vec::with_capacity(self.recipients_names.len()); + let name_iter = self.recipients_names.iter(); + let addr_iter = self.recipients_addr.iter(); + for (name, addr) in name_iter.zip(addr_iter) { + if name.is_empty() { + to.push(Address::new_mailbox(addr.clone())); + } else { + to.push(Address::new_mailbox_with_name( + dc_encode_header_words(name), + addr.clone(), + )); + } + } + + if !self.references.is_empty() { + unprotected_headers.push(Header::new("References".into(), self.references.clone())); + } + + if !self.in_reply_to.is_empty() { + unprotected_headers.push(Header::new("In-Reply-To".into(), self.in_reply_to.clone())); + } + + let date = chrono::Utc + .from_local_datetime(&chrono::NaiveDateTime::from_timestamp(self.timestamp, 0)) + .unwrap() + .to_rfc2822(); + + unprotected_headers.push(Header::new("Date".into(), date)); + + let os_name = &self.context.os_name; + let os_part = os_name + .as_ref() + .map(|s| format!("/{}", s)) + .unwrap_or_default(); + let version = get_version_str(); + + // Add a X-Mailer header. + // This is only informational for debugging and may be removed in the release. + // We do not rely on this header as it may be removed by MTAs. + + unprotected_headers.push(Header::new( + "X-Mailer".into(), + format!("Delta Chat Core {}{}", version, os_part), + )); + unprotected_headers.push(Header::new("Chat-Version".to_string(), "1.0".to_string())); + + if self.req_mdn { + // we use "Chat-Disposition-Notification-To" + // because replies to "Disposition-Notification-To" are weird in many cases + // eg. are just freetext and/or do not follow any standard. + protected_headers.push(Header::new( + "Chat-Disposition-Notification-To".into(), + self.from_addr.clone(), + )); + } + + let min_verified = self.min_verified(); + let do_gossip = self.should_do_gossip(); + let grpimage = self.grpimage(); + let force_plaintext = self.should_force_plaintext(); + let subject_str = self.subject_str(); + let e2ee_guranteed = self.is_e2ee_guranteed(); + let mut encrypt_helper = EncryptHelper::new(self.context)?; + + let subject = dc_encode_header_words(subject_str); + + let mut message = match self.loaded { + Loaded::Message => { + self.render_message(&mut protected_headers, &mut unprotected_headers, &grpimage)? + } + Loaded::MDN => self.render_mdn()?, + }; + + if force_plaintext != DC_FP_NO_AUTOCRYPT_HEADER { + // unless determined otherwise we add the Autocrypt header + let aheader = encrypt_helper.get_aheader().to_string(); + unprotected_headers.push(Header::new("Autocrypt".into(), aheader)); + } + + protected_headers.push(Header::new("Subject".into(), subject)); + + let peerstates = self.peerstates_for_recipients()?; + let should_encrypt = + encrypt_helper.should_encrypt(self.context, e2ee_guranteed, &peerstates)?; + let is_encrypted = should_encrypt && force_plaintext == 0; + + // Add gossip headers + if do_gossip { + for peerstate in peerstates.iter().filter_map(|(state, _)| state.as_ref()) { + if peerstate.peek_key(min_verified).is_some() { + if let Some(header) = peerstate.render_gossip_header(min_verified) { + protected_headers.push(Header::new("Autocrypt-Gossip".into(), header)); + } + } + } + } + + let rfc724_mid = match self.loaded { + Loaded::Message => self.msg.rfc724_mid.clone(), + Loaded::MDN => dc_create_outgoing_rfc724_mid(None, &self.from_addr), + }; + + protected_headers.push(Header::new("Message-ID".into(), rfc724_mid.clone())); + + unprotected_headers.push(Header::new_with_value("To".into(), to).unwrap()); + unprotected_headers.push(Header::new_with_value("From".into(), vec![from]).unwrap()); + + let outer_message = if is_encrypted { + // Store protected headers in the inner message. + for header in protected_headers.into_iter() { + message = message.header(header); + } + // Set the appropriate Content-Type for the inner message. + let mut existing_ct = message + .get_header("Content-Type".to_string()) + .and_then(|h| h.get_value::().ok()) + .unwrap_or_else(|| "text/plain; charset=utf-8;".to_string()); + + if !existing_ct.ends_with(';') { + existing_ct += ";"; + } + message = message.replace_header(Header::new( + "Content-Type".to_string(), + format!("{} protected-headers=\"v1\";", existing_ct), + )); + + // Set the appropriate Content-Type for the outer message + let mut outer_message = PartBuilder::new().header(( + "Content-Type".to_string(), + "multipart/encrypted; protocol=\"application/pgp-encrypted\";".to_string(), + )); + + // Store the unprotected headers on the outer message. + for header in unprotected_headers.into_iter() { + outer_message = outer_message.header(header); + } + + let encrypted = + encrypt_helper.encrypt(self.context, min_verified, message, &peerstates)?; + + outer_message = outer_message + .child( + // Autocrypt part 1 + PartBuilder::new() + .content_type(&"application/pgp-encrypted".parse::().unwrap()) + .header(("Content-Description", "PGP/MIME version identification")) + .body("Version: 1\r\n") + .build(), + ) + .child( + // Autocrypt part 2 + PartBuilder::new() + .content_type( + &"application/octet-stream; name=\"encrypted.asc\"" + .parse::() + .unwrap(), + ) + .header(("Content-Description", "OpenPGP encrypted message")) + .header(("Content-Disposition", "inline; filename=\"encrypted.asc\";")) + .body(encrypted) + .build(), + ) + .header(("Subject".to_string(), "...".to_string())); + + outer_message + } else { + // In the unencrypted case, we add all headers to the outer message. + for header in protected_headers.into_iter() { + message = message.header(header); + } + for header in unprotected_headers.into_iter() { + message = message.header(header); + } + message + }; + + let is_gossiped = is_encrypted && do_gossip && !peerstates.is_empty(); + + let MimeFactory { + recipients_addr, + from_addr, + last_added_location_id, + msg, + loaded, + .. + } = self; + + Ok(RenderedEmail { + message: outer_message.build().as_string().into_bytes(), + // envelope: Envelope::new, + is_encrypted, + is_gossiped, + last_added_location_id, + foreign_id: match loaded { + Loaded::Message => Some(msg.id), + Loaded::MDN => None, + }, + recipients: recipients_addr, + from: from_addr, + rfc724_mid, + }) } - let chat = chat.unwrap(); - let raw_subject = - message::get_summarytext_by_raw(msg.type_0, msg.text.as_ref(), &mut msg.param, 32, context); - let fwd = if afwd_email { "Fwd: " } else { "" }; + fn render_message( + &mut self, + protected_headers: &mut Vec
, + unprotected_headers: &mut Vec
, + grpimage: &Option, + ) -> Result { + let context = self.context; + let chat = self.chat.as_ref().unwrap(); + let command = self.msg.param.get_cmd(); + let mut placeholdertext = None; + let mut meta_part = None; - if msg.param.get_cmd() == SystemMessage::AutocryptSetupMessage { - /* do not add the "Chat:" prefix for setup messages */ - context - .stock_str(StockMessage::AcSetupMsgSubject) - .into_owned() - } else if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup { - format!("Chat: {}: {}{}", chat.name, fwd, raw_subject,) - } else { - format!("Chat: {}{}", fwd, raw_subject) + if chat.typ == Chattype::VerifiedGroup { + protected_headers.push(Header::new("Chat-Verified".to_string(), "1".to_string())); + } + + if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup { + protected_headers.push(Header::new("Chat-Group-ID".into(), chat.grpid.clone())); + + let encoded = dc_encode_header_words(&chat.name); + protected_headers.push(Header::new("Chat-Group-Name".into(), encoded)); + + match command { + SystemMessage::MemberRemovedFromGroup => { + let email_to_remove = self.msg.param.get(Param::Arg).unwrap_or_default(); + if !email_to_remove.is_empty() { + protected_headers.push(Header::new( + "Chat-Group-Member-Removed".into(), + email_to_remove.into(), + )); + } + } + SystemMessage::MemberAddedToGroup => { + let email_to_add = self.msg.param.get(Param::Arg).unwrap_or_default(); + if !email_to_add.is_empty() { + protected_headers.push(Header::new( + "Chat-Group-Member-Added".into(), + email_to_add.into(), + )); + } + if 0 != self.msg.param.get_int(Param::Arg2).unwrap_or_default() & 0x1 { + info!( + context, + "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", + "vg-member-added", + ); + protected_headers.push(Header::new( + "Secure-Join".to_string(), + "vg-member-added".to_string(), + )); + } + } + SystemMessage::GroupNameChanged => { + let value_to_add = self.msg.param.get(Param::Arg).unwrap_or_default(); + + protected_headers.push(Header::new( + "Chat-Group-Name-Changed".into(), + value_to_add.into(), + )); + } + SystemMessage::GroupImageChanged => { + if grpimage.is_none() { + protected_headers + .push(Header::new("Chat-Group-Image".to_string(), "0".to_string())); + } + } + _ => {} + } + } + + match command { + SystemMessage::LocationStreamingEnabled => { + protected_headers.push(Header::new( + "Chat-Content".into(), + "location-streaming-enabled".into(), + )); + } + SystemMessage::AutocryptSetupMessage => { + unprotected_headers + .push(Header::new("Autocrypt-Setup-Message".into(), "v1".into())); + + placeholdertext = Some( + self.context + .stock_str(StockMessage::AcSetupMsgBody) + .to_string(), + ); + } + SystemMessage::SecurejoinMessage => { + let msg = &self.msg; + let step = msg.param.get(Param::Arg).unwrap_or_default(); + if !step.is_empty() { + info!( + context, + "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", step, + ); + protected_headers.push(Header::new("Secure-Join".into(), step.into())); + + let param2 = msg.param.get(Param::Arg2).unwrap_or_default(); + if !param2.is_empty() { + protected_headers.push(Header::new( + if step == "vg-request-with-auth" || step == "vc-request-with-auth" { + "Secure-Join-Auth".into() + } else { + "Secure-Join-Invitenumber".into() + }, + param2.into(), + )); + } + + let fingerprint = msg.param.get(Param::Arg3).unwrap_or_default(); + if !fingerprint.is_empty() { + protected_headers.push(Header::new( + "Secure-Join-Fingerprint".into(), + fingerprint.into(), + )); + } + if let Some(id) = msg.param.get(Param::Arg4) { + protected_headers.push(Header::new("Secure-Join-Group".into(), id.into())); + }; + } + } + _ => {} + } + + if let Some(grpimage) = grpimage { + info!(self.context, "setting group image '{}'", grpimage); + let mut meta = Message::default(); + meta.type_0 = Viewtype::Image; + meta.param.set(Param::File, grpimage); + + let (mail, filename_as_sent) = build_body_file(context, &meta, "group-image")?; + meta_part = Some(mail); + protected_headers.push(Header::new("Chat-Group-Image".into(), filename_as_sent)); + } + + if self.msg.type_0 == Viewtype::Sticker { + protected_headers.push(Header::new("Chat-Content".into(), "sticker".into())); + } + + if self.msg.type_0 == Viewtype::Voice + || self.msg.type_0 == Viewtype::Audio + || self.msg.type_0 == Viewtype::Video + { + if self.msg.type_0 == Viewtype::Voice { + protected_headers.push(Header::new("Chat-Voice-Message".into(), "1".into())); + } + let duration_ms = self.msg.param.get_int(Param::Duration).unwrap_or_default(); + if duration_ms > 0 { + let dur = duration_ms.to_string(); + protected_headers.push(Header::new("Chat-Duration".into(), dur)); + } + } + + // add text part - we even add empty text and force a MIME-multipart-message as: + // - some Apps have problems with Non-text in the main part (eg. "Mail" from stock Android) + // - we can add "forward hints" this way + // - it looks better + + let afwd_email = self.msg.param.exists(Param::Forwarded); + let fwdhint = if afwd_email { + Some( + "---------- Forwarded message ----------\r\n\ + From: Delta Chat\r\n\ + \r\n" + .to_string(), + ) + } else { + None + }; + let final_text = { + if let Some(ref text) = placeholdertext { + text + } else if let Some(ref text) = self.msg.text { + text + } else { + "" + } + }; + + let footer = &self.selfstatus; + let message_text = format!( + "{}{}{}{}{}", + fwdhint.unwrap_or_default(), + &final_text, + if !final_text.is_empty() && !footer.is_empty() { + "\r\n\r\n" + } else { + "" + }, + if !footer.is_empty() { "-- \r\n" } else { "" }, + footer + ); + + // Message is sent as text/plain, with charset = utf-8 + let mut parts = vec![PartBuilder::new() + .content_type(&mime::TEXT_PLAIN_UTF_8) + .body(message_text)]; + + // add attachment part + if chat::msgtype_has_file(self.msg.type_0) { + if !is_file_size_okay(context, &self.msg) { + bail!( + "Message exceeds the recommended {} MB.", + 24 * 1024 * 1024 / 4 * 3 / 1000 / 1000, + ); + } else { + let (file_part, _) = build_body_file(context, &self.msg, "")?; + parts.push(file_part); + } + } + + if let Some(meta_part) = meta_part { + parts.push(meta_part); + } + + if self.msg.param.exists(Param::SetLatitude) { + let param = &self.msg.param; + let kml_file = location::get_message_kml( + self.msg.timestamp_sort, + param.get_float(Param::SetLatitude).unwrap_or_default(), + param.get_float(Param::SetLongitude).unwrap_or_default(), + ); + parts.push( + PartBuilder::new() + .content_type( + &"application/vnd.google-earth.kml+xml" + .parse::() + .unwrap(), + ) + .header(( + "Content-Disposition", + "attachment; filename=\"message.kml\"", + )) + .body(kml_file), + ); + } + + if location::is_sending_locations_to_chat(context, self.msg.chat_id) { + match location::get_kml(context, self.msg.chat_id) { + Ok((kml_content, last_added_location_id)) => { + parts.push( + PartBuilder::new() + .content_type( + &"application/vnd.google-earth.kml+xml" + .parse::() + .unwrap(), + ) + .header(( + "Content-Disposition", + "attachment; filename=\"message.kml\"", + )) + .body(kml_content), + ); + if !self.msg.param.exists(Param::SetLatitude) { + // otherwise, the independent location is already filed + self.last_added_location_id = last_added_location_id; + } + } + Err(err) => { + warn!(context, "mimefactory: could not get location: {}", err); + } + } + } + + // Single part, render as regular message. + if parts.len() == 1 { + return Ok(parts.pop().unwrap()); + } + + // Multiple parts, render as multipart. + let mut message = PartBuilder::new().message_type(MimeMultipartType::Mixed); + for part in parts.into_iter() { + message = message.child(part.build()); + } + + Ok(message) + } + + /// Render an MDN + fn render_mdn(&mut self) -> Result { + // RFC 6522, this also requires the `report-type` parameter which is equal + // to the MIME subtype of the second body part of the multipart/report */ + // + // currently, we do not send MDNs encrypted: + // - in a multi-device-setup that is not set up properly, MDNs would disturb the communication as they + // are send automatically which may lead to spreading outdated Autocrypt headers. + // - they do not carry any information but the Message-ID + // - this save some KB + // - in older versions, we did not encrypt messages to ourself when they to to SMTP - however, if these messages + // are forwarded for any reasons (eg. gmail always forwards to IMAP), we have no chance to decrypt them; + // this issue is fixed with 0.9.4 + + let mut message = PartBuilder::new().header(( + "Content-Type".to_string(), + "multipart/report; report-type=disposition-notification".to_string(), + )); + + // first body part: always human-readable, always REQUIRED by RFC 6522 + let p1 = if 0 + != self + .msg + .param + .get_int(Param::GuaranteeE2ee) + .unwrap_or_default() + { + self.context + .stock_str(StockMessage::EncryptedMsg) + .into_owned() + } else { + self.msg.get_summarytext(self.context, 32) + }; + let p2 = self + .context + .stock_string_repl_str(StockMessage::ReadRcptMailBody, p1); + let message_text = format!("{}\r\n", p2); + message = message.child( + PartBuilder::new() + .content_type(&mime::TEXT_PLAIN_UTF_8) + .body(message_text) + .build(), + ); + + // second body part: machine-readable, always REQUIRED by RFC 6522 + let version = get_version_str(); + let message_text2 = format!( + "Reporting-UA: Delta Chat {}\r\n\ + Original-Recipient: rfc822;{}\r\n\ + Final-Recipient: rfc822;{}\r\n\ + Original-Message-ID: <{}>\r\n\ + Disposition: manual-action/MDN-sent-automatically; displayed\r\n", + version, self.from_addr, self.from_addr, self.msg.rfc724_mid + ); + + message = message.child( + PartBuilder::new() + .content_type(&"message/disposition-notification".parse().unwrap()) + .body(message_text2) + .build(), + ); + + Ok(message) } } -#[allow(non_snake_case)] fn build_body_file( context: &Context, msg: &Message, base_name: &str, -) -> Result<(*mut Mailmime, String), Error> { +) -> Result<(PartBuilder, String), Error> { let blob = msg .param .get_blob(Param::File, context, true)? @@ -825,73 +968,43 @@ fn build_body_file( }; /* check mimetype */ - let mimetype = match msg.param.get(Param::MimeType) { - Some(mtype) => mtype, + let mimetype: mime::Mime = match msg.param.get(Param::MimeType) { + Some(mtype) => mtype.parse()?, None => { if let Some(res) = message::guess_msgtype_from_suffix(blob.as_rel_path()) { - res.1 + res.1.parse()? } else { - "application/octet-stream" + mime::APPLICATION_OCTET_STREAM } } }; let needs_ext = dc_needs_ext_header(&filename_to_send); - unsafe { - /* create mime part, for Content-Disposition, see RFC 2183. - `Content-Disposition: attachment` seems not to make a difference to `Content-Disposition: inline` at least on tested Thunderbird and Gma'l in 2017. - But I've heard about problems with inline and outl'k, so we just use the attachment-type until we run into other problems ... */ - let mime_fields = mailmime_fields_new_filename( - MAILMIME_DISPOSITION_TYPE_ATTACHMENT as libc::c_int, - if needs_ext { - ptr::null_mut() - } else { - filename_to_send.strdup() - }, - MAILMIME_MECHANISM_BASE64 as libc::c_int, - ); - if needs_ext { - for cur_data in (*(*mime_fields).fld_list).into_iter() { - let field: *mut mailmime_field = cur_data as *mut _; - if (*field).fld_type == MAILMIME_FIELD_DISPOSITION as libc::c_int - && !(*field).fld_data.fld_disposition.is_null() - { - let file_disposition = (*field).fld_data.fld_disposition; - if !file_disposition.is_null() { - let parm = mailmime_disposition_parm_new( - MAILMIME_DISPOSITION_PARM_PARAMETER as libc::c_int, - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - 0 as libc::size_t, - mailmime_parameter_new( - strdup(b"filename*\x00" as *const u8 as *const libc::c_char), - dc_encode_ext_header(&filename_to_send).strdup(), - ), - ); - if !parm.is_null() { - clist_insert_after( - (*file_disposition).dsp_parms, - (*(*file_disposition).dsp_parms).last, - parm as *mut libc::c_void, - ); - } - } - break; - } - } - } - let content = wrapmime::new_content_type(&mimetype)?; - let filename_encoded = dc_encode_header_words(&filename_to_send); - wrapmime::append_ct_param(content, "name", &filename_encoded)?; + // create mime part, for Content-Disposition, see RFC 2183. + // `Content-Disposition: attachment` seems not to make a difference to `Content-Disposition: inline` + // at least on tested Thunderbird and Gma'l in 2017. + // But I've heard about problems with inline and outl'k, so we just use the attachment-type until we + // run into other problems ... + let cd_value = if needs_ext { + format!("attachment; filename=\"{}\"", &filename_to_send) + } else { + format!( + "attachment; filename*=\"{}\"", + dc_encode_header_words(&filename_to_send) + ) + }; - let mime_sub = mailmime_new_empty(content, mime_fields); - let abs_path = blob.to_abs_path().to_c_string()?; - mailmime_set_body_file(mime_sub, dc_strdup(abs_path.as_ptr())); - Ok((mime_sub, filename_to_send)) - } + let body = std::fs::read(blob.to_abs_path())?; + let encoded_body = base64::encode(&body); + + let mail = PartBuilder::new() + .content_type(&mimetype) + .header(("Content-Disposition", cd_value)) + .header(("Content-Transfer-Encoding", "base64")) + .body(encoded_body); + + Ok((mail, filename_to_send)) } pub(crate) fn vec_contains_lowercase(vec: &[String], part: &str) -> bool { diff --git a/src/mimeparser.rs b/src/mimeparser.rs new file mode 100644 index 000000000..31085ce5c --- /dev/null +++ b/src/mimeparser.rs @@ -0,0 +1,1109 @@ +use std::collections::{HashMap, HashSet}; + +use deltachat_derive::{FromSql, ToSql}; +use lettre_email::mime::{self, Mime}; +use mailparse::MailHeaderMap; + +use crate::aheader::Aheader; +use crate::blob::BlobObject; +use crate::config::Config; +use crate::constants::Viewtype; +use crate::contact::*; +use crate::context::Context; +use crate::dc_simplify::*; +use crate::dc_tools::*; +use crate::e2ee; +use crate::error::Result; +use crate::job::{job_add, Action}; +use crate::location; +use crate::message; +use crate::message::MsgId; +use crate::param::*; +use crate::peerstate::Peerstate; +use crate::securejoin::handle_degrade_event; +use crate::stock::StockMessage; + +#[derive(Debug)] +pub struct MimeParser<'a> { + pub context: &'a Context, + pub parts: Vec, + pub header: HashMap, + pub subject: Option, + pub is_send_by_messenger: bool, + pub decrypting_failed: bool, + pub encrypted: bool, + pub signatures: HashSet, + pub gossipped_addr: HashSet, + pub is_forwarded: bool, + pub is_system_message: SystemMessage, + pub location_kml: Option, + pub message_kml: Option, + reports: Vec, + mdns_enabled: bool, + parsed_protected_headers: bool, +} + +#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, ToSql, FromSql)] +#[repr(i32)] +pub enum SystemMessage { + Unknown = 0, + GroupNameChanged = 2, + GroupImageChanged = 3, + MemberAddedToGroup = 4, + MemberRemovedFromGroup = 5, + AutocryptSetupMessage = 6, + SecurejoinMessage = 7, + LocationStreamingEnabled = 8, + LocationOnly = 9, +} + +impl Default for SystemMessage { + fn default() -> Self { + SystemMessage::Unknown + } +} + +const MIME_AC_SETUP_FILE: &str = "application/autocrypt-setup"; + +impl<'a> MimeParser<'a> { + pub fn from_bytes(context: &'a Context, body: &[u8]) -> Result { + let mail = mailparse::parse_mail(body)?; + let mdns_enabled = context.get_config_bool(Config::MdnsEnabled); + + let mut parser = MimeParser { + parts: Vec::new(), + header: Default::default(), + subject: None, + is_send_by_messenger: false, + decrypting_failed: false, + encrypted: false, + signatures: Default::default(), + gossipped_addr: Default::default(), + is_forwarded: false, + context, + reports: Vec::new(), + is_system_message: SystemMessage::Unknown, + location_kml: None, + message_kml: None, + mdns_enabled, + parsed_protected_headers: false, + }; + + let message_time = mail + .headers + .get_first_value("Date")? + .and_then(|v| mailparse::dateparse(&v).ok()) + .unwrap_or_default(); + + parser.hash_header(&mail.headers); + + // Memory location for a possible decrypted message. + let mail_raw; + + let mail = match e2ee::try_decrypt(parser.context, &mail, message_time) { + Ok((raw, signatures)) => { + // Valid autocrypt message, encrypted + parser.encrypted = raw.is_some(); + parser.signatures = signatures; + + if let Some(raw) = raw { + mail_raw = raw; + let decrypted_mail = mailparse::parse_mail(&mail_raw)?; + + // Handle any gossip headers if the mail was encrypted. See section + // "3.6 Key Gossip" of https://autocrypt.org/autocrypt-spec-1.1.0.pdf + let gossip_headers = + decrypted_mail.headers.get_all_values("Autocrypt-Gossip")?; + parser.gossipped_addr = + update_gossip_peerstates(context, message_time, &mail, gossip_headers)?; + + decrypted_mail + } else { + // Message was not encrypted + mail + } + } + Err(err) => { + // continue with the current, still encrypted, mime tree. + // unencrypted parts will be replaced by an error message + // that is added as "the message" to the chat then. + // + // if we just return here, the header is missing + // and the caller cannot display the message + // and try to assign the message to a chat + warn!(parser.context, "decryption failed: {}", err); + mail + } + }; + + parser.parse_mime_recursive(&mail)?; + + parser.parse_headers()?; + + Ok(parser) + } + + fn parse_headers(&mut self) -> Result<()> { + if let Some(field) = self.lookup_field("Subject") { + self.subject = Some(field.clone()); + } + + if let Some(_) = self.lookup_field("Chat-Version") { + self.is_send_by_messenger = true + } + + if let Some(_) = self.lookup_field("Autocrypt-Setup-Message") { + let has_setup_file = self.parts.iter().any(|p| { + p.mimetype.is_some() && p.mimetype.as_ref().unwrap().as_ref() == MIME_AC_SETUP_FILE + }); + + if has_setup_file { + self.is_system_message = SystemMessage::AutocryptSetupMessage; + + // TODO: replace the following code with this + // once drain_filter stabilizes. + // + // See https://doc.rust-lang.org/std/vec/struct.Vec.html#method.drain_filter + // and https://github.com/rust-lang/rust/issues/43244 + // + // mimeparser + // .parts + // .drain_filter(|part| part.int_mimetype != 111) + // .for_each(|part| dc_mimepart_unref(part)); + + let mut i = 0; + while i != self.parts.len() { + let mimetype = &self.parts[i].mimetype; + if mimetype.is_none() + || mimetype.as_ref().unwrap().as_ref() != MIME_AC_SETUP_FILE + { + self.parts.remove(i); + } else { + i += 1; + } + } + } + } else if let Some(value) = self.lookup_field("Chat-Content") { + if value == "location-streaming-enabled" { + self.is_system_message = SystemMessage::LocationStreamingEnabled; + } + } + if let Some(_) = self.lookup_field("Chat-Group-Image") { + if !self.parts.is_empty() { + let textpart = &self.parts[0]; + if textpart.typ == Viewtype::Text && self.parts.len() >= 2 { + let imgpart = &mut self.parts[1]; + if imgpart.typ == Viewtype::Image { + imgpart.is_meta = true; + } + } + } + } + + if self.is_send_by_messenger && self.parts.len() == 2 { + let need_drop = { + let textpart = &self.parts[0]; + let filepart = &self.parts[1]; + textpart.typ == Viewtype::Text + && (filepart.typ == Viewtype::Image + || filepart.typ == Viewtype::Gif + || filepart.typ == Viewtype::Sticker + || filepart.typ == Viewtype::Audio + || filepart.typ == Viewtype::Voice + || filepart.typ == Viewtype::Video + || filepart.typ == Viewtype::File) + && !filepart.is_meta + }; + + if need_drop { + let mut filepart = self.parts.swap_remove(1); + + // insert new one + filepart.msg = self.parts[0].msg.clone(); + + // forget the one we use now + self.parts[0].msg = "".to_string(); + + // swap new with old + std::mem::replace(&mut self.parts[0], filepart); + } + } + if let Some(ref subject) = self.subject { + let mut prepend_subject = 1i32; + if !self.decrypting_failed { + let colon = subject.find(':'); + if colon == Some(2) + || colon == Some(3) + || self.is_send_by_messenger + || subject.contains("Chat:") + { + prepend_subject = 0i32 + } + } + if 0 != prepend_subject { + let subj = if let Some(n) = subject.find('[') { + &subject[0..n] + } else { + subject + } + .trim(); + + if !subj.is_empty() { + for part in self.parts.iter_mut() { + if part.typ == Viewtype::Text { + part.msg = format!("{} – {}", subj, part.msg); + break; + } + } + } + } + } + if self.is_forwarded { + for part in self.parts.iter_mut() { + part.param.set_int(Param::Forwarded, 1); + } + } + if self.parts.len() == 1 { + if self.parts[0].typ == Viewtype::Audio { + if let Some(_) = self.lookup_field("Chat-Voice-Message") { + let part_mut = &mut self.parts[0]; + part_mut.typ = Viewtype::Voice; + } + } + if self.parts[0].typ == Viewtype::Image { + if let Some(value) = self.lookup_field("Chat-Content") { + if value == "sticker" { + let part_mut = &mut self.parts[0]; + part_mut.typ = Viewtype::Sticker; + } + } + } + let part = &self.parts[0]; + if part.typ == Viewtype::Audio + || part.typ == Viewtype::Voice + || part.typ == Viewtype::Video + { + if let Some(field_0) = self.lookup_field("Chat-Duration") { + let duration_ms = field_0.parse().unwrap_or_default(); + if duration_ms > 0 && duration_ms < 24 * 60 * 60 * 1000 { + let part_mut = &mut self.parts[0]; + part_mut.param.set_int(Param::Duration, duration_ms); + } + } + } + } + if !self.decrypting_failed { + if let Some(dn_field) = self.lookup_field("Chat-Disposition-Notification-To") { + if self.get_last_nonmeta().is_some() { + let addrs = mailparse::addrparse(&dn_field).unwrap(); + + if let Some(dn_to_addr) = addrs.first() { + if let Some(from_field) = self.lookup_field("From") { + let from_addrs = mailparse::addrparse(&from_field).unwrap(); + + if let Some(from_addr) = from_addrs.first() { + if compare_addrs(from_addr, dn_to_addr) { + if let Some(part_4) = self.get_last_nonmeta_mut() { + part_4.param.set_int(Param::WantsMdn, 1); + } + } + } + } + } + } + } + } + + // Cleanup - and try to create at least an empty part if there are no parts yet + if self.get_last_nonmeta().is_none() && self.reports.is_empty() { + let mut part = Part::default(); + part.typ = Viewtype::Text; + + if let Some(ref subject) = self.subject { + if !self.is_send_by_messenger { + part.msg = subject.to_string(); + } + } + + self.parts.push(part); + } + + Ok(()) + } + + pub fn get_last_nonmeta(&self) -> Option<&Part> { + self.parts.iter().rev().find(|part| !part.is_meta) + } + + pub fn get_last_nonmeta_mut(&mut self) -> Option<&mut Part> { + self.parts.iter_mut().rev().find(|part| !part.is_meta) + } + + pub fn lookup_field(&self, field_name: &str) -> Option<&String> { + self.header.get(&field_name.to_lowercase()) + } + + fn parse_mime_recursive(&mut self, mail: &mailparse::ParsedMail<'_>) -> Result { + if mail.ctype.params.get("protected-headers").is_some() { + if mail.ctype.mimetype == "text/rfc822-headers" { + warn!( + self.context, + "Protected headers found in text/rfc822-headers attachment: Will be ignored.", + ); + return Ok(false); + } + + if self.parsed_protected_headers { + warn!(self.context, "Ignoring nested protected headers"); + } else { + self.hash_header(&mail.headers); + self.parsed_protected_headers = true; + } + } + + enum MimeS { + Multiple, + Single, + Message, + } + + let mimetype = mail.ctype.mimetype.to_lowercase(); + + let m = if mimetype.starts_with("multipart") { + if mail.ctype.params.get("boundary").is_some() { + MimeS::Multiple + } else { + MimeS::Single + } + } else if mimetype.starts_with("message") { + if mimetype == "message/rfc822" { + MimeS::Message + } else { + MimeS::Single + } + } else { + MimeS::Single + }; + + match m { + MimeS::Multiple => self.handle_multiple(mail), + MimeS::Message => { + let raw = mail.get_body_raw()?; + if raw.is_empty() { + return Ok(false); + } + let mail = mailparse::parse_mail(&raw).unwrap(); + + self.parse_mime_recursive(&mail) + } + MimeS::Single => self.add_single_part_if_known(mail), + } + } + + fn handle_multiple(&mut self, mail: &mailparse::ParsedMail<'_>) -> Result { + let mut any_part_added = false; + let mimetype = get_mime_type(mail)?.0; + match (mimetype.type_(), mimetype.subtype().as_str()) { + /* Most times, mutlipart/alternative contains true alternatives + as text/plain and text/html. If we find a multipart/mixed + inside mutlipart/alternative, we use this (happens eg in + apple mail: "plaintext" as an alternative to "html+PDF attachment") */ + (mime::MULTIPART, "alternative") => { + for cur_data in &mail.subparts { + if get_mime_type(cur_data)?.0 == "multipart/mixed" { + any_part_added = self.parse_mime_recursive(cur_data)?; + break; + } + } + if !any_part_added { + /* search for text/plain and add this */ + for cur_data in &mail.subparts { + if get_mime_type(cur_data)?.0.type_() == mime::TEXT { + any_part_added = self.parse_mime_recursive(cur_data)?; + break; + } + } + } + if !any_part_added { + /* `text/plain` not found - use the first part */ + for cur_part in &mail.subparts { + if self.parse_mime_recursive(cur_part)? { + any_part_added = true; + break; + } + } + } + } + (mime::MULTIPART, "related") => { + /* add the "root part" - the other parts may be referenced which is + not interesting for us (eg. embedded images) we assume he "root part" + being the first one, which may not be always true ... + however, most times it seems okay. */ + if let Some(first) = mail.subparts.iter().next() { + any_part_added = self.parse_mime_recursive(first)?; + } + } + (mime::MULTIPART, "encrypted") => { + let msg_body = self.context.stock_str(StockMessage::CantDecryptMsgBody); + let txt = format!("[{}]", msg_body); + + let mut part = Part::default(); + part.typ = Viewtype::Text; + part.msg_raw = Some(txt.clone()); + part.msg = txt; + + self.parts.push(part); + + any_part_added = true; + self.decrypting_failed = true; + } + (mime::MULTIPART, "signed") => { + /* RFC 1847: "The multipart/signed content type + contains exactly two body parts. The first body + part is the body part over which the digital signature was created [...] + The second body part contains the control information necessary to + verify the digital signature." We simpliy take the first body part and + skip the rest. (see + https://k9mail.github.io/2016/11/24/OpenPGP-Considerations-Part-I.html + for background information why we use encrypted+signed) */ + if let Some(first) = mail.subparts.iter().next() { + any_part_added = self.parse_mime_recursive(first)?; + } + } + (mime::MULTIPART, "report") => { + /* RFC 6522: the first part is for humans, the second for machines */ + if mail.subparts.len() >= 2 { + if let Some(report_type) = mail.ctype.params.get("report-type") { + if report_type == "disposition-notification" { + if let Some(report) = self.process_report(mail)? { + self.reports.push(report); + } + } else { + /* eg. `report-type=delivery-status`; + maybe we should show them as a little error icon */ + if let Some(first) = mail.subparts.iter().next() { + any_part_added = self.parse_mime_recursive(first)?; + } + } + } + } + } + _ => { + // Add all parts (in fact, + // AddSinglePartIfKnown() later check if the parts are really supported) + // HACK: the following lines are a hack for clients who use + // multipart/mixed instead of multipart/alternative for + // combined text/html messages (eg. Stock Android "Mail" does so). + // So, if we detect such a message below, we skip the Html + // part. However, not sure, if there are useful situations to use + // plain+html in multipart/mixed - if so, we should disable the hack. + let mut skip_part = -1; + let mut html_part = -1; + let mut plain_cnt = 0; + let mut html_cnt = 0; + + for (i, cur_data) in mail.subparts.iter().enumerate() { + match get_mime_type(cur_data)?.0.type_() { + mime::TEXT => { + plain_cnt += 1; + } + mime::HTML => { + html_part = i as isize; + html_cnt += 1; + } + _ => {} + } + } + if plain_cnt == 1 && html_cnt == 1 { + warn!( + self.context, + "HACK: multipart/mixed message found with Plain and HTML, we\'ll skip the HTML part as this seems to be unwanted." + ); + skip_part = html_part; + } + + for (i, cur_data) in mail.subparts.iter().enumerate() { + if i as isize != skip_part && self.parse_mime_recursive(cur_data)? { + any_part_added = true; + } + } + } + } + + Ok(any_part_added) + } + + fn add_single_part_if_known(&mut self, mail: &mailparse::ParsedMail<'_>) -> Result { + // return true if a part was added + let (mime_type, msg_type) = get_mime_type(mail)?; + let raw_mime = mail.ctype.mimetype.to_lowercase(); + + let old_part_count = self.parts.len(); + + // regard `Content-Transfer-Encoding:` + match mime_type.type_() { + mime::TEXT | mime::HTML => { + let decoded_data = match mail.get_body() { + Ok(decoded_data) => decoded_data, + Err(err) => { + warn!(self.context, "Invalid body parsed {:?}", err); + // Note that it's not always an error - might be no data + return Ok(false); + } + }; + + // check header directly as is_send_by_messenger is not yet set up + let is_msgrmsg = self.lookup_field("Chat-Version").is_some(); + + let mut simplifier = Simplify::new(); + let simplified_txt = if decoded_data.is_empty() { + "".into() + } else { + let is_html = mime_type == mime::TEXT_HTML; + simplifier.simplify(&decoded_data, is_html, is_msgrmsg) + }; + + if !simplified_txt.is_empty() { + let mut part = Part::default(); + part.typ = Viewtype::Text; + part.mimetype = Some(mime_type); + part.msg = simplified_txt; + part.msg_raw = Some(decoded_data); + self.do_add_single_part(part); + } + + if simplifier.is_forwarded { + self.is_forwarded = true; + } + } + mime::IMAGE | mime::AUDIO | mime::VIDEO | mime::APPLICATION => { + // try to get file name from + // `Content-Disposition: ... filename*=...` + // or `Content-Disposition: ... filename*0*=... filename*1*=... filename*2*=...` + // or `Content-Disposition: ... filename=...` + + let ct = mail.get_content_disposition()?; + let mut desired_filename = ct + .params + .iter() + .filter(|(key, _value)| key.starts_with("filename")) + .fold(String::new(), |mut acc, (_key, value)| { + acc += value; + acc + }); + + if desired_filename.is_empty() { + if let Some(param) = ct.params.get("name") { + // might be a wrongly encoded filename + desired_filename = param.to_string(); + } + } + + // if there is still no filename, guess one + if desired_filename.is_empty() { + if let Some(subtype) = mail.ctype.mimetype.split('/').skip(1).next() { + desired_filename = format!("file.{}", subtype,); + } else { + return Ok(false); + } + } + self.do_add_single_file_part( + msg_type, + mime_type, + &raw_mime, + &mail.get_body_raw()?, + &desired_filename, + ); + } + _ => {} + } + + // add object? (we do not add all objects, eg. signatures etc. are ignored) + Ok(self.parts.len() > old_part_count) + } + + fn do_add_single_file_part( + &mut self, + msg_type: Viewtype, + mime_type: Mime, + raw_mime: &String, + decoded_data: &[u8], + filename: &str, + ) { + if decoded_data.is_empty() { + return; + } + // treat location/message kml file attachments specially + if filename.ends_with(".kml") { + // XXX what if somebody sends eg an "location-highlights.kml" + // attachment unrelated to location streaming? + if filename.starts_with("location") || filename.starts_with("message") { + let parsed = location::Kml::parse(self.context, decoded_data) + .map_err(|err| { + warn!(self.context, "failed to parse kml part: {}", err); + }) + .ok(); + if filename.starts_with("location") { + self.location_kml = parsed; + } else { + self.message_kml = parsed; + } + return; + } + } + /* we have a regular file attachment, + write decoded data to new blob object */ + + let blob = match BlobObject::create(self.context, filename, decoded_data) { + Ok(blob) => blob, + Err(err) => { + error!( + self.context, + "Could not add blob for mime part {}, error {}", filename, err + ); + return; + } + }; + + /* create and register Mime part referencing the new Blob object */ + let mut part = Part::default(); + if mime_type.type_() == mime::IMAGE { + if let Ok((width, height)) = dc_get_filemeta(decoded_data) { + part.param.set_int(Param::Width, width as i32); + part.param.set_int(Param::Height, height as i32); + } + } + + part.typ = msg_type; + part.mimetype = Some(mime_type); + part.bytes = decoded_data.len(); + part.param.set(Param::File, blob.as_name()); + part.param.set(Param::MimeType, raw_mime); + + self.do_add_single_part(part); + } + + fn do_add_single_part(&mut self, mut part: Part) { + if self.encrypted { + if self.signatures.len() > 0 { + part.param.set_int(Param::GuaranteeE2ee, 1); + } else { + // XXX if the message was encrypted but not signed + // it's not neccessarily an error we need to signal. + // we could just treat it as if it was not encrypted. + part.param.set_int(Param::ErroneousE2ee, 0x2); + } + } + self.parts.push(part); + } + + pub fn is_mailinglist_message(&self) -> bool { + if let Some(_) = self.lookup_field("List-Id") { + return true; + } + + if let Some(precedence) = self.lookup_field("Precedence") { + if precedence == "list" || precedence == "bulk" { + return true; + } + } + + false + } + + pub fn sender_equals_recipient(&self) -> bool { + /* get From: and check there is exactly one sender */ + if let Some(field) = self.lookup_field("From") { + if let Ok(addrs) = mailparse::addrparse(field) { + if addrs.len() != 1 { + return false; + } + if let mailparse::MailAddr::Single(ref info) = addrs[0] { + let from_addr_norm = addr_normalize(&info.addr); + let recipients = get_recipients(self.header.iter()); + if recipients.len() == 1 && recipients.contains(from_addr_norm) { + return true; + } + } + } + } + false + } + + pub fn repl_msg_by_error(&mut self, error_msg: impl AsRef) { + if self.parts.is_empty() { + return; + } + + let part = &mut self.parts[0]; + part.typ = Viewtype::Text; + part.msg = format!("[{}]", error_msg.as_ref()); + self.parts.truncate(1); + + assert_eq!(self.parts.len(), 1); + } + + pub fn get_rfc724_mid(&self) -> Option { + // get Message-ID from header + if let Some(field) = self.lookup_field("Message-ID") { + return parse_message_id(field); + } + None + } + + fn hash_header(&mut self, fields: &[mailparse::MailHeader<'_>]) { + for field in fields { + if let Ok(key) = field.get_key() { + // lowercasing all headers is technically not correct, but makes things work better + let key = key.to_lowercase(); + if !self.header.contains_key(&key) || // key already exists, only overwrite known types (protected headers) + is_known(&key) || key.starts_with("chat-") + { + if let Ok(value) = field.get_value() { + self.header.insert(key, value); + } + } + } + } + } + + fn process_report(&self, report: &mailparse::ParsedMail<'_>) -> Result> { + // to get a clear functionality, do not show incoming MDNs if the options is disabled + if !self.mdns_enabled { + return Ok(None); + } + + // parse as mailheaders + let report_body = report.subparts[1].get_body_raw()?; + let (report_fields, _) = mailparse::parse_headers(&report_body)?; + + // must be present + if let Some(_disposition) = report_fields.get_first_value("Disposition").ok().flatten() { + if let Some(original_message_id) = report_fields + .get_first_value("Original-Message-ID") + .ok() + .flatten() + .and_then(|v| parse_message_id(&v)) + { + return Ok(Some(Report { + original_message_id, + })); + } + } + + Ok(None) + } + + // Handle reports (mainly MDNs) + pub fn handle_reports( + &self, + from_id: u32, + sent_timestamp: i64, + rr_event_to_send: &mut Vec<(u32, MsgId)>, + server_folder: impl AsRef, + server_uid: u32, + ) { + for report in &self.reports { + let mut mdn_consumed = false; + + if let Some((chat_id, msg_id)) = message::mdn_from_ext( + self.context, + from_id, + &report.original_message_id, + sent_timestamp, + ) { + rr_event_to_send.push((chat_id, msg_id)); + mdn_consumed = true; + } + + if self.is_send_by_messenger || mdn_consumed { + let mut param = Params::new(); + param.set(Param::ServerFolder, server_folder.as_ref()); + param.set_int(Param::ServerUid, server_uid as i32); + if self.is_send_by_messenger && self.context.get_config_bool(Config::MvboxMove) { + param.set_int(Param::AlsoMove, 1); + } + job_add(self.context, Action::MarkseenMdnOnImap, 0, param, 0); + } + } + } +} + +fn update_gossip_peerstates( + context: &Context, + message_time: i64, + mail: &mailparse::ParsedMail<'_>, + gossip_headers: Vec, +) -> Result> { + // XXX split the parsing from the modification part + let mut recipients: Option> = None; + let mut gossipped_addr: HashSet = Default::default(); + + for value in &gossip_headers { + let gossip_header = value.parse::(); + + if let Ok(ref header) = gossip_header { + if recipients.is_none() { + recipients = Some(get_recipients(mail.headers.iter().filter_map(|v| { + let key = v.get_key(); + let value = v.get_value(); + if key.is_err() || value.is_err() { + return None; + } + Some((v.get_key().unwrap(), v.get_value().unwrap())) + }))); + } + + if recipients.as_ref().unwrap().contains(&header.addr) { + let mut peerstate = Peerstate::from_addr(context, &context.sql, &header.addr); + if let Some(ref mut peerstate) = peerstate { + peerstate.apply_gossip(header, message_time); + peerstate.save_to_db(&context.sql, false)?; + } else { + let p = Peerstate::from_gossip(context, header, message_time); + p.save_to_db(&context.sql, true)?; + peerstate = Some(p); + } + if let Some(peerstate) = peerstate { + if peerstate.degrade_event.is_some() { + handle_degrade_event(context, &peerstate)?; + } + } + + gossipped_addr.insert(header.addr.clone()); + } else { + warn!( + context, + "Ignoring gossipped \"{}\" as the address is not in To/Cc list.", &header.addr, + ); + } + } + } + + Ok(gossipped_addr) +} + +#[derive(Debug)] +struct Report { + original_message_id: String, +} + +fn parse_message_id(field: &str) -> Option { + if let Ok(addrs) = mailparse::addrparse(field) { + // Assume the message id is a single id in the form of + if let mailparse::MailAddr::Single(mailparse::SingleInfo { ref addr, .. }) = addrs[0] { + return Some(addr.clone()); + } + } + None +} + +fn is_known(key: &str) -> bool { + match key { + "return-path" | "date" | "from" | "sender" | "reply-to" | "to" | "cc" | "bcc" + | "message-id" | "in-reply-to" | "references" | "subject" => true, + _ => false, + } +} + +#[derive(Debug, Default, Clone)] +pub struct Part { + pub typ: Viewtype, + pub is_meta: bool, + pub mimetype: Option, + pub msg: String, + pub msg_raw: Option, + pub bytes: usize, + pub param: Params, +} + +fn get_mime_type(mail: &mailparse::ParsedMail<'_>) -> Result<(Mime, Viewtype)> { + let mimetype = mail.ctype.mimetype.parse::()?; + + let viewtype = match mimetype.type_() { + mime::TEXT => { + if !mailmime_is_attachment_disposition(mail) { + match mimetype.subtype() { + mime::PLAIN | mime::HTML => Viewtype::Text, + _ => Viewtype::File, + } + } else { + Viewtype::File + } + } + mime::IMAGE => match mimetype.subtype() { + mime::GIF => Viewtype::Gif, + mime::SVG => Viewtype::File, + _ => Viewtype::Image, + }, + mime::AUDIO => Viewtype::Audio, + mime::VIDEO => Viewtype::Video, + mime::MULTIPART => Viewtype::Unknown, + mime::MESSAGE => { + // Enacapsulated messages, see https://www.w3.org/Protocols/rfc1341/7_3_Message.html + // Also used as part "message/disposition-notification" of "multipart/report", which, however, will + // be handled separatedly. + // I've not seen any messages using this, so we do not attach these parts (maybe they're used to attach replies, + // which are unwanted at all). + // For now, we skip these parts at all; if desired, we could return DcMimeType::File/DC_MSG_File + // for selected and known subparts. + Viewtype::Unknown + } + mime::APPLICATION => Viewtype::File, + _ => Viewtype::Unknown, + }; + + Ok((mimetype, viewtype)) +} + +fn mailmime_is_attachment_disposition(mail: &mailparse::ParsedMail<'_>) -> bool { + if let Some(ct) = mail.ctype.params.get("Content-Disposition") { + return ct.to_lowercase().starts_with("attachment"); + } + + false +} + +// returned addresses are normalized. +fn get_recipients<'a, S: AsRef, T: Iterator>(headers: T) -> HashSet { + let mut recipients: HashSet = Default::default(); + + for (hkey, hvalue) in headers { + let hkey = hkey.as_ref(); + let hvalue = hvalue.as_ref(); + + if hkey == "to" || hkey == "cc" { + if let Ok(addrs) = mailparse::addrparse(hvalue) { + for addr in addrs.iter() { + match addr { + mailparse::MailAddr::Single(ref info) => { + recipients.insert(addr_normalize(&info.addr).into()); + } + mailparse::MailAddr::Group(ref infos) => { + for info in &infos.addrs { + recipients.insert(addr_normalize(&info.addr).into()); + } + } + } + } + } + } + } + + recipients +} + +/// Check if the only addrs match, ignoring names. +fn compare_addrs(a: &mailparse::MailAddr, b: &mailparse::MailAddr) -> bool { + match a { + mailparse::MailAddr::Group(group_a) => match b { + mailparse::MailAddr::Group(group_b) => group_a + .addrs + .iter() + .zip(group_b.addrs.iter()) + .all(|(a, b)| a.addr == b.addr), + _ => false, + }, + mailparse::MailAddr::Single(single_a) => match b { + mailparse::MailAddr::Single(single_b) => single_a.addr == single_b.addr, + _ => false, + }, + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_utils::*; + use proptest::prelude::*; + + #[test] + fn test_dc_mimeparser_crash() { + let context = dummy_context(); + let raw = include_bytes!("../test-data/message/issue_523.txt"); + let mimeparser = MimeParser::from_bytes(&context.ctx, &raw[..]).unwrap(); + + assert_eq!(mimeparser.subject, None); + assert_eq!(mimeparser.parts.len(), 1); + } + + proptest! { + #[ignore] + #[test] + fn test_dc_mailmime_parse_crash_fuzzy(data in "[!-~\t ]{2000,}") { + let context = dummy_context(); + + // just don't crash + let _ = MimeParser::from_bytes(&context.ctx, data.as_bytes()); + } + } + + #[test] + fn test_get_rfc724_mid_exists() { + let context = dummy_context(); + let raw = include_bytes!("../test-data/message/mail_with_message_id.txt"); + let mimeparser = MimeParser::from_bytes(&context.ctx, &raw[..]).unwrap(); + + assert_eq!( + mimeparser.get_rfc724_mid(), + Some("2dfdbde7@example.org".into()) + ); + } + + #[test] + fn test_get_rfc724_mid_not_exists() { + let context = dummy_context(); + let raw = include_bytes!("../test-data/message/issue_523.txt"); + let mimeparser = MimeParser::from_bytes(&context.ctx, &raw[..]).unwrap(); + assert_eq!(mimeparser.get_rfc724_mid(), None); + } + + #[test] + fn test_mailparse_content_type() { + let ctype = + mailparse::parse_content_type("text/plain; charset=utf-8; protected-headers=v1;"); + + assert_eq!(ctype.mimetype, "text/plain"); + assert_eq!(ctype.charset, "utf-8"); + assert_eq!( + ctype.params.get("protected-headers"), + Some(&"v1".to_string()) + ); + } + + #[test] + fn test_mimeparser_with_context() { + let context = dummy_context(); + let raw = b"From: hello\n\ + Content-Type: multipart/mixed; boundary=\"==break==\";\n\ + Subject: outer-subject\n\ + X-Special-A: special-a\n\ + Foo: Bar\nChat-Version: 0.0\n\ + \n\ + --==break==\n\ + Content-Type: text/plain; protected-headers=\"v1\";\n\ + Subject: inner-subject\n\ + X-Special-B: special-b\n\ + Foo: Xy\n\ + Chat-Version: 1.0\n\ + \n\ + test1\n\ + \n\ + --==break==--\n\ + \n\ + \x00"; + let mimeparser = MimeParser::from_bytes(&context.ctx, &raw[..]).unwrap(); + + assert_eq!(mimeparser.subject, Some("inner-subject".into())); + + let of = mimeparser.lookup_field("X-Special-A").unwrap(); + assert_eq!(of, "special-a"); + + let of = mimeparser.lookup_field("Foo").unwrap(); + assert_eq!(of, "Bar"); + + let of = mimeparser.lookup_field("Chat-Version").unwrap(); + assert_eq!(of, "1.0"); + assert_eq!(mimeparser.parts.len(), 1); + } +} diff --git a/src/param.rs b/src/param.rs index 908ba7923..8fc0891fc 100644 --- a/src/param.rs +++ b/src/param.rs @@ -7,8 +7,8 @@ use num_traits::FromPrimitive; use crate::blob::{BlobError, BlobObject}; use crate::context::Context; -use crate::dc_mimeparser::SystemMessage; use crate::error; +use crate::mimeparser::SystemMessage; /// Available param keys. #[derive(PartialEq, Eq, Debug, Clone, Copy, Hash, PartialOrd, Ord, FromPrimitive)] diff --git a/src/securejoin.rs b/src/securejoin.rs index d252bb811..85d6b2cd4 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -8,13 +8,13 @@ use crate::config::*; use crate::constants::*; use crate::contact::*; use crate::context::Context; -use crate::dc_mimeparser::*; use crate::e2ee::*; use crate::error::Error; use crate::events::Event; use crate::key::*; use crate::lot::LotState; use crate::message::Message; +use crate::mimeparser::*; use crate::param::*; use crate::peerstate::*; use crate::qr::check_qr; @@ -337,7 +337,7 @@ impl Default for HandshakeMessageStatus { } } -/* library private: secure-join */ +/// Handle incoming secure-join handshake. pub(crate) fn handle_securejoin_handshake( context: &Context, mimeparser: &MimeParser, @@ -349,22 +349,22 @@ pub(crate) fn handle_securejoin_handshake( contact_id > DC_CONTACT_ID_LAST_SPECIAL, "handle_securejoin_handshake(): called with special contact id" ); - let step = match mimeparser.lookup_optional_field("Secure-Join") { - Some(s) => s, - None => { - bail!("This message is not a Secure-Join message"); - } - }; + let step = mimeparser + .lookup_field("Secure-Join") + .ok_or_else(|| format_err!("This message is not a Secure-Join message"))?; + info!( context, ">>>>>>>>>>>>>>>>>>>>>>>>> secure-join message \'{}\' received", step, ); + let (contact_chat_id, contact_chat_id_blocked) = chat::create_or_lookup_by_contact_id(context, contact_id, Blocked::Not).unwrap_or_default(); if contact_chat_id_blocked != Blocked::Not { chat::unblock(context, contact_chat_id); } + let join_vg = step.starts_with("vg-"); let mut ret = HandshakeMessageStatus::default(); @@ -378,7 +378,7 @@ pub(crate) fn handle_securejoin_handshake( // it just ensures, we have Bobs key now. If we do _not_ have the key because eg. MitM has removed it, // send_message() will fail with the error "End-to-end-encryption unavailable unexpectedly.", so, there is no additional check needed here. // verify that the `Secure-Join-Invitenumber:`-header matches invitenumber written to the QR code - let invitenumber = match mimeparser.lookup_optional_field("Secure-Join-Invitenumber") { + let invitenumber = match mimeparser.lookup_field("Secure-Join-Invitenumber") { Some(n) => n, None => { warn!(context, "Secure-join denied (invitenumber missing).",); @@ -467,7 +467,7 @@ pub(crate) fn handle_securejoin_handshake( ==== Step 6 in "Out-of-band verified groups" protocol ==== ============================================================ */ // verify that Secure-Join-Fingerprint:-header matches the fingerprint of Bob - let fingerprint = match mimeparser.lookup_optional_field("Secure-Join-Fingerprint") { + let fingerprint = match mimeparser.lookup_field("Secure-Join-Fingerprint") { Some(fp) => fp, None => { could_not_establish_secure_connection( @@ -496,7 +496,7 @@ pub(crate) fn handle_securejoin_handshake( } info!(context, "Fingerprint verified.",); // verify that the `Secure-Join-Auth:`-header matches the secret written to the QR code - let auth_0 = match mimeparser.lookup_optional_field("Secure-Join-Auth") { + let auth_0 = match mimeparser.lookup_field("Secure-Join-Auth") { Some(auth) => auth, None => { could_not_establish_secure_connection( @@ -526,9 +526,10 @@ pub(crate) fn handle_securejoin_handshake( inviter_progress!(context, contact_id, 600); if join_vg { let field_grpid = mimeparser - .lookup_optional_field("Secure-Join-Group") - .unwrap_or_default(); - let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, &field_grpid); + .lookup_field("Secure-Join-Group") + .map(|s| s.as_str()) + .unwrap_or_else(|| ""); + let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, field_grpid); if group_chat_id == 0 { error!(context, "Chat {} not found.", &field_grpid); return Ok(ret); @@ -601,8 +602,9 @@ pub(crate) fn handle_securejoin_handshake( Contact::scaleup_origin_by_id(context, contact_id, Origin::SecurejoinJoined); emit_event!(context, Event::ContactsChanged(None)); let cg_member_added = mimeparser - .lookup_optional_field("Chat-Group-Member-Added") - .unwrap_or_default(); + .lookup_field("Chat-Group-Member-Added") + .map(|s| s.as_str()) + .unwrap_or_else(|| ""); if join_vg && !addr_equals_self(context, cg_member_added) { info!(context, "Message belongs to a different handshake (scaled up contact anyway to allow creation of group)."); return Ok(ret); @@ -635,8 +637,9 @@ pub(crate) fn handle_securejoin_handshake( inviter_progress!(context, contact_id, 800); inviter_progress!(context, contact_id, 1000); let field_grpid = mimeparser - .lookup_optional_field("Secure-Join-Group") - .unwrap_or_default(); + .lookup_field("Secure-Join-Group") + .map(|s| s.as_str()) + .unwrap_or_else(|| ""); let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, &field_grpid); context.call_cb(Event::SecurejoinMemberAdded { chat_id: group_chat_id, @@ -651,9 +654,11 @@ pub(crate) fn handle_securejoin_handshake( warn!(context, "invalid step: {}", step); } } + if ret.hide_this_msg { ret.delete_this_msg = true; } + Ok(ret) } diff --git a/src/wrapmime.rs b/src/wrapmime.rs index c8cc7fda3..6021d5eee 100644 --- a/src/wrapmime.rs +++ b/src/wrapmime.rs @@ -1,552 +1,50 @@ -use std::collections::HashSet; -use std::ffi::CString; -use std::ptr; +use mailparse::ParsedMail; -use crate::contact::addr_normalize; -use crate::dc_strencode::*; -use crate::dc_tools::*; use crate::error::Error; -use mmime::clist::*; -// use mmime::display::*; -use mmime::mailimf::mailimf_msg_id_parse; -use mmime::mailimf::types::*; -use mmime::mailimf::types_helper::*; -use mmime::mailmime::content::*; -use mmime::mailmime::disposition::*; -use mmime::mailmime::types::*; -use mmime::mailmime::types_helper::*; -use mmime::mailmime::*; -use mmime::mmapstring::*; -use mmime::other::*; - -#[macro_export] -macro_rules! clist_append { - ($clist:expr, $item:expr) => { - if clist_insert_after( - $clist as *mut clist, - (*$clist).last, - $item as *mut libc::c_void, - ) != 0 - { - bail!("could not allocate or append list item"); - } - }; -} - -/************************************** -* mime parsing API -**************************************/ - -pub fn get_ct_subtype(mime: *mut Mailmime) -> Option { - unsafe { - let ct: *mut mailmime_content = (*mime).mm_content_type; - - if !ct.is_null() && !(*ct).ct_subtype.is_null() { - Some(to_string_lossy((*ct).ct_subtype)) - } else { - None - } - } -} pub fn parse_message_id(message_id: &[u8]) -> Result { - let mut dummy = 0; - let mut rfc724_mid_c = std::ptr::null_mut(); - if unsafe { - mailimf_msg_id_parse( - message_id.as_ptr() as *const libc::c_char, - message_id.len(), - &mut dummy, - &mut rfc724_mid_c, - ) - } == MAIL_NO_ERROR as libc::c_int - && !rfc724_mid_c.is_null() - { - let res = to_string_lossy(rfc724_mid_c); - unsafe { libc::free(rfc724_mid_c.cast()) }; - Ok(res) - } else { - bail!( - "could not parse message_id: {}", - String::from_utf8_lossy(message_id) - ); + let value = std::str::from_utf8(message_id)?; + let addrs = mailparse::addrparse(value) + .map_err(|err| format_err!("failed to parse message id {:?}", err))?; + + if let Some(info) = addrs.extract_single_info() { + return Ok(info.addr); } + + bail!("could not parse message_id: {}", value); } -pub fn get_autocrypt_mime( - mime_undetermined: *mut Mailmime, -) -> Result<(*mut Mailmime, *mut Mailmime), Error> { - /* return Result with two mime pointers: +/// Returns a reference to the encrypted payload and validates the autocrypt structure. +pub fn get_autocrypt_mime<'a, 'b>(mail: &'a ParsedMail<'b>) -> Result<&'a ParsedMail<'b>, Error> { + ensure!( + mail.ctype.mimetype == "multipart/encrypted", + "Not a multipart/encrypted message: {}", + mail.ctype.mimetype + ); + ensure!( + mail.subparts.len() == 2, + "Invalid Autocrypt Level 1 Mime Parts" + ); - First mime pointer is to the multipart-mime message - (which is replaced with a decrypted version later) + ensure!( + mail.subparts[0].ctype.mimetype == "application/pgp-encrypted", + "Invalid Autocrypt Level 1 version part: {:?}", + mail.subparts[0].ctype, + ); - Second one is to the encrypted payload. - For non-autocrypt message an Error is returned. - */ - unsafe { - ensure!( - (*mime_undetermined).mm_type == MAILMIME_MESSAGE as libc::c_int, - "Not a root mime message" - ); - let mime = (*mime_undetermined).mm_data.mm_message.mm_msg_mime; + ensure!( + mail.subparts[1].ctype.mimetype == "application/octet-stream", + "Invalid Autocrypt Level 1 encrypted part: {:?}", + mail.subparts[1].ctype + ); - ensure!( - (*mime).mm_type == MAILMIME_MULTIPLE as libc::c_int - && "encrypted" == get_ct_subtype(mime).unwrap_or_default(), - "Not a multipart/encrypted message" - ); - let parts: Vec<_> = (*(*mime).mm_data.mm_multipart.mm_mp_list) - .into_iter() - .map(|c| c as *mut Mailmime) - .collect(); - ensure!(parts.len() == 2, "Invalid Autocrypt Level 1 Mime Parts"); - // XXX ensure protocol-parameter "application/pgp-encrypted") - // XXX ensure wrapmime::get_content_type(parts[1])) == "application/octetstream" - // a proper OpenPGP multipart/encrypted Autocrypt Level 1 message - // https://tools.ietf.org/html/rfc3156.html#section-4 - Ok((mime, parts[1])) - } -} - -pub fn has_decryptable_data(mime_data: *mut mailmime_data) -> bool { - /* MAILMIME_DATA_FILE indicates, the data is in a file; AFAIK this is not used on parsing */ - unsafe { - (*mime_data).dt_type == MAILMIME_DATA_TEXT as libc::c_int - && !(*mime_data).dt_data.dt_text.dt_data.is_null() - && (*mime_data).dt_data.dt_text.dt_length > 0 - } -} - -pub fn get_field_from(imffields: *mut mailimf_fields) -> Result { - let field = mailimf_find_field(imffields, MAILIMF_FIELD_FROM as libc::c_int); - if !field.is_null() && unsafe { !(*field).fld_data.fld_from.is_null() } { - let mb_list = unsafe { (*(*field).fld_data.fld_from).frm_mb_list }; - if let Some(addr) = mailimf_find_first_addr(mb_list) { - return Ok(addr); - } - } - bail!("not From field found"); -} - -pub fn get_field_date(imffields: *mut mailimf_fields) -> Result { - let field = mailimf_find_field(imffields, MAILIMF_FIELD_ORIG_DATE as libc::c_int); - let mut message_time = 0; - - if !field.is_null() && unsafe { !(*field).fld_data.fld_orig_date.is_null() } { - let orig_date = unsafe { (*field).fld_data.fld_orig_date }; - - if !orig_date.is_null() { - let dt = unsafe { (*orig_date).dt_date_time }; - message_time = dc_timestamp_from_date(dt); - if message_time != 0 && message_time > time() { - message_time = time() - } - } - } - - Ok(message_time) -} - -fn mailimf_get_recipients_add_addr(recipients: &mut HashSet, mb: *mut mailimf_mailbox) { - if !mb.is_null() { - let addr = to_string_lossy(unsafe { (*mb).mb_addr_spec }); - let addr_norm = addr_normalize(&addr); - recipients.insert(addr_norm.into()); - } -} - -/*the result is a pointer to mime, must not be freed*/ -pub fn mailimf_find_field( - header: *mut mailimf_fields, - wanted_fld_type: libc::c_int, -) -> *mut mailimf_field { - if header.is_null() { - return ptr::null_mut(); - } - - let header = unsafe { (*header) }; - if header.fld_list.is_null() { - return ptr::null_mut(); - } - - for cur in unsafe { &(*header.fld_list) } { - let field = cur as *mut mailimf_field; - if !field.is_null() { - if unsafe { (*field).fld_type } == wanted_fld_type { - return field; - } - } - } - - ptr::null_mut() -} - -/*the result is a pointer to mime, must not be freed*/ -pub fn mailmime_find_mailimf_fields(mime: *mut Mailmime) -> *mut mailimf_fields { - if mime.is_null() { - return ptr::null_mut(); - } - - match unsafe { (*mime).mm_type as _ } { - MAILMIME_MULTIPLE => { - for cur_data in unsafe { (*(*mime).mm_data.mm_multipart.mm_mp_list).into_iter() } { - let header = mailmime_find_mailimf_fields(cur_data as *mut _); - if !header.is_null() { - return header; - } - } - } - MAILMIME_MESSAGE => return unsafe { (*mime).mm_data.mm_message.mm_fields }, - _ => {} - } - - ptr::null_mut() -} - -pub unsafe fn mailimf_find_optional_field( - header: *mut mailimf_fields, - wanted_fld_name: *const libc::c_char, -) -> *mut mailimf_optional_field { - if header.is_null() || (*header).fld_list.is_null() { - return ptr::null_mut(); - } - for cur_data in (*(*header).fld_list).into_iter() { - let field: *mut mailimf_field = cur_data as *mut _; - - if (*field).fld_type == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int { - let optional_field: *mut mailimf_optional_field = (*field).fld_data.fld_optional_field; - if !optional_field.is_null() - && !(*optional_field).fld_name.is_null() - && !(*optional_field).fld_value.is_null() - && strcasecmp((*optional_field).fld_name, wanted_fld_name) == 0i32 - { - return optional_field; - } - } - } - - ptr::null_mut() -} - -pub fn mailimf_get_recipients(imffields: *mut mailimf_fields) -> HashSet { - /* returned addresses are normalized. */ - let mut recipients: HashSet = Default::default(); - - for cur in unsafe { (*(*imffields).fld_list).into_iter() } { - let fld = cur as *mut mailimf_field; - - let fld_to: *mut mailimf_to; - let fld_cc: *mut mailimf_cc; - - let mut addr_list: *mut mailimf_address_list = ptr::null_mut(); - if fld.is_null() { - continue; - } - - let fld = unsafe { *fld }; - - // TODO match on enums /rtn - match fld.fld_type { - 13 => { - fld_to = unsafe { fld.fld_data.fld_to }; - if !fld_to.is_null() { - addr_list = unsafe { (*fld_to).to_addr_list }; - } - } - 14 => { - fld_cc = unsafe { fld.fld_data.fld_cc }; - if !fld_cc.is_null() { - addr_list = unsafe { (*fld_cc).cc_addr_list }; - } - } - _ => {} - } - - if !addr_list.is_null() { - for cur2 in unsafe { &(*(*addr_list).ad_list) } { - let adr = cur2 as *mut mailimf_address; - - if adr.is_null() { - continue; - } - let adr = unsafe { *adr }; - - if adr.ad_type == MAILIMF_ADDRESS_MAILBOX as libc::c_int { - mailimf_get_recipients_add_addr(&mut recipients, unsafe { - adr.ad_data.ad_mailbox - }); - } else if adr.ad_type == MAILIMF_ADDRESS_GROUP as libc::c_int { - let group = unsafe { adr.ad_data.ad_group }; - if !group.is_null() && unsafe { !(*group).grp_mb_list.is_null() } { - for cur3 in unsafe { &(*(*(*group).grp_mb_list).mb_list) } { - mailimf_get_recipients_add_addr( - &mut recipients, - cur3 as *mut mailimf_mailbox, - ); - } - } - } - } - } - } - - recipients -} - -pub fn mailmime_transfer_decode(mime: *mut Mailmime) -> Result, Error> { - ensure!(!mime.is_null(), "invalid inputs"); - - let mime_transfer_encoding = - get_mime_transfer_encoding(mime).unwrap_or(MAILMIME_MECHANISM_BINARY as i32); - - let mime_data = unsafe { (*mime).mm_data.mm_single }; - - decode_dt_data(mime_data, mime_transfer_encoding) -} - -pub fn get_mime_transfer_encoding(mime: *mut Mailmime) -> Option { - unsafe { - let mm_mime_fields = (*mime).mm_mime_fields; - if !mm_mime_fields.is_null() { - for cur_data in (*(*mm_mime_fields).fld_list).into_iter() { - let field: *mut mailmime_field = cur_data as *mut _; - if (*field).fld_type == MAILMIME_FIELD_TRANSFER_ENCODING as libc::c_int - && !(*field).fld_data.fld_encoding.is_null() - { - return Some((*(*field).fld_data.fld_encoding).enc_type); - } - } - } - } - None -} - -pub fn decode_dt_data( - mime_data: *mut mailmime_data, - mime_transfer_encoding: libc::c_int, -) -> Result, Error> { - // Decode data according to mime_transfer_encoding - // returns Ok with a (decoded_data,decoded_data_bytes) pointer - // where the caller must make sure to free it. - // It may return Ok(ptr::null_mut(), 0) - if mime_transfer_encoding == MAILMIME_MECHANISM_7BIT as libc::c_int - || mime_transfer_encoding == MAILMIME_MECHANISM_8BIT as libc::c_int - || mime_transfer_encoding == MAILMIME_MECHANISM_BINARY as libc::c_int - { - let decoded_data = unsafe { (*mime_data).dt_data.dt_text.dt_data }; - let decoded_data_bytes = unsafe { (*mime_data).dt_data.dt_text.dt_length }; - - if decoded_data.is_null() || decoded_data_bytes == 0 { - bail!("No data to decode found"); - } else { - let result = unsafe { - std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes) - }; - return Ok(result.to_vec()); - } - } - // unsafe { display_mime_data(mime_data) }; - - let mut current_index = 0; - let mut transfer_decoding_buffer = ptr::null_mut(); - let mut decoded_data_bytes = 0; - - let r = unsafe { - mailmime_part_parse( - (*mime_data).dt_data.dt_text.dt_data, - (*mime_data).dt_data.dt_text.dt_length, - &mut current_index, - mime_transfer_encoding, - &mut transfer_decoding_buffer, - &mut decoded_data_bytes, - ) - }; - - if r == MAILIMF_NO_ERROR as libc::c_int - && !transfer_decoding_buffer.is_null() - && decoded_data_bytes > 0 - { - let result = unsafe { - std::slice::from_raw_parts(transfer_decoding_buffer as *const u8, decoded_data_bytes) - } - .to_vec(); - // we return a fresh vec and transfer_decoding_buffer is not used or passed anywhere - // so it's safe to free it right away, as mailman_part_parse has - // allocated it fresh. - unsafe { mmap_string_unref(transfer_decoding_buffer) }; - - return Ok(result); - } - - Err(format_err!("Failed to to decode")) -} - -pub fn mailimf_find_first_addr(mb_list: *const mailimf_mailbox_list) -> Option { - if mb_list.is_null() { - return None; - } - - for cur in unsafe { (*(*mb_list).mb_list).into_iter() } { - let mb = cur as *mut mailimf_mailbox; - if !mb.is_null() && !unsafe { (*mb).mb_addr_spec.is_null() } { - let addr = unsafe { to_string_lossy((*mb).mb_addr_spec) }; - return Some(addr_normalize(&addr).to_string()); - } - } - - None -} - -/************************************** -* mime creation API -**************************************/ - -pub fn add_filename_part( - message: *mut Mailmime, - basename: &str, - mime_type: &str, - file_content: &str, -) -> Result<(), Error> { - let mime_type_c = CString::new(mime_type.to_string()).expect("failed to create CString"); - unsafe { - let content_type = mailmime_content_new_with_str(mime_type_c.as_ptr()); - let mime_fields = mailmime_fields_new_filename( - MAILMIME_DISPOSITION_TYPE_ATTACHMENT as libc::c_int, - basename.strdup(), - MAILMIME_MECHANISM_8BIT as libc::c_int, - ); - let file_mime_part = mailmime_new_empty(content_type, mime_fields); - set_body_text(file_mime_part, file_content)?; - mailmime_smart_add_part(message, file_mime_part); - } - Ok(()) -} - -pub fn new_custom_field(fields: *mut mailimf_fields, name: &str, value: &str) { - unsafe { - let field = mailimf_field_new_custom(name.strdup(), value.strdup()); - let res = mailimf_fields_add(fields, field); - assert!( - res as u32 == MAILIMF_NO_ERROR, - "could not create mailimf field" - ); - } -} - -pub fn build_body_text(text: &str) -> Result<*mut Mailmime, Error> { - let mime_fields: *mut mailmime_fields; - let message_part: *mut Mailmime; - - let content = new_content_type("text/plain")?; - append_ct_param(content, "charset", "utf-8")?; - - unsafe { - mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT as libc::c_int); - message_part = mailmime_new_empty(content, mime_fields); - } - set_body_text(message_part, text)?; - - Ok(message_part) -} - -pub fn append_ct_param( - content: *mut mailmime_content, - name: &str, - value: &str, -) -> Result<(), Error> { - unsafe { - let name_c = CString::new(name).unwrap_or_default(); - let value_c = CString::new(value).unwrap_or_default(); - - clist_append!( - (*content).ct_parameters, - mailmime_param_new_with_data( - name_c.as_ptr() as *const u8 as *const libc::c_char as *mut libc::c_char, - value_c.as_ptr() as *const u8 as *const libc::c_char as *mut libc::c_char - ) - ); - } - Ok(()) -} - -pub fn new_content_type(content_type: &str) -> Result<*mut mailmime_content, Error> { - let ct = CString::new(content_type).unwrap_or_default(); - let content: *mut mailmime_content; - // mailmime_content_new_with_str only parses but does not retain/own ct - unsafe { - content = mailmime_content_new_with_str(ct.as_ptr()); - } - ensure!(!content.is_null(), "mailimf failed to allocate"); - Ok(content) -} - -pub fn set_body_text(part: *mut Mailmime, text: &str) -> Result<(), Error> { - use libc::strlen; - unsafe { - let text_c = text.strdup(); - if 0 != mailmime_set_body_text(part, text_c, strlen(text_c)) { - bail!("could not set body text on mime-structure"); - } - } - Ok(()) -} - -pub fn content_type_needs_encoding(content: *const mailmime_content) -> bool { - unsafe { - if (*(*content).ct_type).tp_type == MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int { - let composite = (*(*content).ct_type).tp_data.tp_composite_type; - match (*composite).ct_type as u32 { - MAILMIME_COMPOSITE_TYPE_MESSAGE => { - to_string_lossy((*content).ct_subtype) != "rfc822" - } - MAILMIME_COMPOSITE_TYPE_MULTIPART => false, - _ => false, - } - } else { - true - } - } -} - -pub fn new_mailbox_list(displayname: &str, addr: &str) -> *mut mailimf_mailbox_list { - let mbox: *mut mailimf_mailbox_list = unsafe { mailimf_mailbox_list_new_empty() }; - unsafe { - mailimf_mailbox_list_add( - mbox, - mailimf_mailbox_new( - if !displayname.is_empty() { - dc_encode_header_words(&displayname).strdup() - } else { - ptr::null_mut() - }, - addr.strdup(), - ), - ); - } - mbox + Ok(&mail.subparts[1]) } #[cfg(test)] mod tests { use super::*; - #[test] - fn test_needs_encoding() { - assert!(content_type_needs_encoding( - new_content_type("text/plain").unwrap() - )); - assert!(content_type_needs_encoding( - new_content_type("application/octect-stream").unwrap() - )); - assert!(!content_type_needs_encoding( - new_content_type("multipart/encrypted").unwrap() - )); - assert!(content_type_needs_encoding( - new_content_type("application/pgp-encrypted").unwrap() - )); - } - #[test] fn test_parse_message_id() { assert_eq!( diff --git a/tests/stress.rs b/tests/stress.rs index f03c9e2c8..9939766e1 100644 --- a/tests/stress.rs +++ b/tests/stress.rs @@ -14,7 +14,7 @@ use tempfile::{tempdir, TempDir}; /* some data used for testing ******************************************************************************/ -unsafe fn stress_functions(context: &Context) { +fn stress_functions(context: &Context) { let res = context.get_config(config::Config::SysConfigKeys).unwrap(); assert!(!res.contains(" probably_never_a_key ")); @@ -224,10 +224,8 @@ fn create_test_context() -> TestContext { #[test] fn test_stress_tests() { - unsafe { - let context = create_test_context(); - stress_functions(&context.ctx); - } + let context = create_test_context(); + stress_functions(&context.ctx); } #[test]