Compare commits

..

54 Commits

Author SHA1 Message Date
holger krekel
e82d76a112 fix #616 -- allow invalid certs for smtp and imap connections -- this is the behaviour of C-core. 2019-09-27 18:37:08 +02:00
holger krekel
f45ee2ab4d fix #615 -- like with c-core Chat-Version is left in unprotected headers because
it's eg used in server-filters for detecting DC messages
2019-09-27 18:28:47 +02:00
holger krekel
2b73fab913 cargo fmt 2019-09-27 18:28:29 +02:00
holger krekel
e0d750ac64 little cleanup dc_imex 2019-09-27 18:28:29 +02:00
Alexander Krotov
bb57c6e7b7 Merge pull request #627 from deltachat/dc_receive_imf-slice
Pass slice to dc_receive_imf
2019-09-27 16:27:14 +00:00
Alexander Krotov
f346a052c1 Return Result from dc_initiate_key_transfer 2019-09-27 17:57:45 +02:00
Alexander Krotov
3933353b5f Pass slice to dc_receive_imf
instead of pointer and length
2019-09-27 17:53:41 +03:00
Dmitry Bogatov
6c9c21c135 quote_word: avoid dependency on phf crate 2019-09-27 04:11:50 +02:00
Dmitry Bogatov
d02a721eed Reimplement dc_encode_header_words in safe Rust
This change fixes proptest, introduced in [THIS~2] commit.
2019-09-27 04:11:50 +02:00
Dmitry Bogatov
8ffb4ae127 Add proptest seed that reveals strencoding bug 2019-09-27 04:11:50 +02:00
Dmitry Bogatov
96fbeb583b Add proptest to check dc_header_{encode,decode} 2019-09-27 04:11:50 +02:00
Dmitry Bogatov
33b98a15d3 Remove unused "print_hex" function 2019-09-27 04:11:50 +02:00
Dmitry Bogatov
e523ebe3c1 Implement safe version of quote_word 2019-09-27 04:11:50 +02:00
Dmitry Bogatov
e17c671b7c Rename local variables to not misleadingly refer to MMAPString 2019-09-27 04:11:50 +02:00
Dmitry Bogatov
e7565e1a2a Use rust strings instead of MMapString in src/dc_strencode.rs
Since Rust strings operations are assumed to never fail, this commit
removes a lot of checking, whether appending to mmapstring fails. Now it
is Rust runtime burden.
2019-09-27 04:11:50 +02:00
B. Petersen
b73d6377fc do not truncate messages in contact requests
core-c has truncated messages in the contact requests.
this is questionable in general, as
- all messages, including contact requests,
  are already truncated, unquoted, simplified etc.
- the ui should be capable of showing the full text anyway
  (when the contact request is accepted, the whole messase is shown)
- also, all current ui show the contact requests by name only in the
  chatlist; the user often does not even come to the contact request view.
- if the ui wants to show the contact request is a special way,
  it is probably better to leave this truncation up to the ui
2019-09-27 02:55:23 +02:00
holger krekel
31f5fffc45 cargo fmt 2019-09-26 20:45:03 +02:00
holger krekel
64c518c2f2 remove ok_to_continue 2019-09-26 20:45:03 +02:00
B. Petersen
1ed543b0e8 adapt group-id length to reality 2019-09-26 20:10:33 +02:00
Floris Bruynooghe
8b7cd2dd1a Revert back to only ffi-level checking of open context
The Rust context is always open, the return value of this function was
simply the wrong way around.
2019-09-26 20:08:36 +02:00
Florian Bruhin
8520b5211a python: Add .venv to .gitignore 2019-09-26 19:20:56 +02:00
Florian Bruhin
03661e2a71 python: Allow to configure debug logging via account 2019-09-26 19:20:56 +02:00
jikstra
20b82b3638 Fix ffi actually calling context.sql.is_open() 2019-09-26 18:36:31 +02:00
Alexander Krotov
cb499ae502 Return Result<String> from dc_decrypt_setup_file 2019-09-26 18:05:29 +02:00
holger krekel
02b73207f9 fixup this PR with tests, and returning None from get_filemime 2019-09-26 17:12:06 +02:00
jikstra
53b5cbc12a get_filemime() should return an empty string if no mimetype is present
and not default to `applicatopm/octet-stream`
2019-09-26 17:12:06 +02:00
Friedel Ziegelmayer
f4c6decd2d refactor(mmime): split up into modules (#609)
refactor(mmime): split up into modules
2019-09-26 15:28:36 +02:00
Floris Bruynooghe
69f1497986 Make dc_get_info() work on a closed context
There is very little API guarantees about this, but clients seem to
expect *something* to work on a closed context.  So split this up into
static info an more dynamic context-related info, but let's not
provide any guarantees about what keys are available when.

Fixes #599
2019-09-26 14:22:03 +02:00
Florian Bruhin
2b46f01fe3 Use sys.executable in install_python_bindings.py
When calling pip this way, the virtualenv is used even if not activated.
2019-09-26 13:09:08 +02:00
dignifiedquire
dd4adb57cf refactor(mmime): remove some duplication 2019-09-26 12:36:23 +02:00
dignifiedquire
452bce07e1 refactor(mmime): split up into modules 2019-09-26 12:36:23 +02:00
Simon Laux
8d702d0b77 rename and update providers crate 2019-09-26 01:42:39 +02:00
holger krekel
e1dc4b69f5 address all @dignifiedquire review comments 2019-09-25 23:46:44 +02:00
holger krekel
6cd3580263 rustifying dc_continue_key_transfer and fix master-conflict 2019-09-25 23:46:44 +02:00
holger krekel
d5383aecc9 finish dc_imex refactoring, fix linting, rustify some things 2019-09-25 23:46:44 +02:00
holger krekel
71cbbab2c9 fix #596 and some cleanups 2019-09-25 23:46:44 +02:00
holger krekel
8518d8f456 rustify imex and friends 2019-09-25 23:46:44 +02:00
holger krekel
adc0db04bc failing test 2019-09-25 23:46:44 +02:00
björn petersen
c61fc59003 Merge pull request #608 from deltachat/fix-get-setupcodebegin
fix boolean error that makes get_setupcodebegin() failing
2019-09-25 21:39:48 +02:00
B. Petersen
40f9072250 add get_setupcodebegin to python bindings, test the function 2019-09-25 21:13:05 +02:00
B. Petersen
ea30bb351e fix boolean error that makes get_setupcodebegin() failing 2019-09-25 20:37:36 +02:00
Alexander Krotov
b93550f6c8 Use DC_MSG_ID_LAST_SPECIAL in dc_continue_key_transfer 2019-09-25 03:29:37 +02:00
Alexander Krotov
60bd053095 Pass setup_code to dc_continue_key_transfer as &str 2019-09-25 03:29:37 +02:00
Alexander Krotov
8165b76001 Make dc_normalize_setup_code safe 2019-09-25 03:29:37 +02:00
jikstra
efc563f5ff fix test 2019-09-25 01:06:42 +02:00
jikstra
e52acc994c Make get_draft() return Ok(None) when called for a special chat id 2019-09-25 01:06:42 +02:00
holger krekel
646833d3ec remove phf crate macro usage: it introduced 7 deps and is really an optimization if you very large (100K+) tables -- we have 10 entries or so and it's called once per message. Let's not introduce crates just because we can -- it increases compile time and in the phf case also introduced a github dependency (for whatever reason -- don't want to know ;) 2019-09-25 00:19:47 +02:00
dignifiedquire
fd72c27afe chore(release): release 1.0.0-alpha.5 2019-09-24 17:26:18 +02:00
dignifiedquire
c13bcc25c6 chore(deps): update lock file 2019-09-24 17:25:03 +02:00
holger krekel
21c9ff6c85 cargo fmt 2019-09-23 23:13:41 +02:00
holger krekel
4d6b367654 remove ok_to_continue from job 2019-09-23 23:13:41 +02:00
holger krekel
e2fd22a78e cargo fmt 2019-09-23 21:23:55 +02:00
holger krekel
0759bdde01 cleanup chat.rs: remove ok_to_continue and return result from add_contact methods 2019-09-23 21:23:55 +02:00
holger krekel
faa03e0e14 no functional code change: rename dc_mimefactory to mimefactory and move some functions to become MimeFactory methods 2019-09-23 20:20:34 +02:00
49 changed files with 1242 additions and 1648 deletions

1
.gitignore vendored
View File

@@ -16,6 +16,7 @@ python/.tox
*.egg-info
__pycache__
python/src/deltachat/capi*.so
python/.venv/
python/liveconfig*

143
Cargo.lock generated
View File

@@ -84,7 +84,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "backtrace"
version = "0.3.37"
version = "0.3.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -130,7 +130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.1.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -317,7 +317,7 @@ name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -419,7 +419,7 @@ dependencies = [
[[package]]
name = "ctor"
version = "0.1.10"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -481,11 +481,11 @@ dependencies = [
[[package]]
name = "deltachat"
version = "1.0.0-alpha.4"
version = "1.0.0-alpha.5"
dependencies = [
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.0 (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)",
@@ -508,7 +508,6 @@ dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pgp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"phf 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
@@ -531,8 +530,8 @@ dependencies = [
]
[[package]]
name = "deltachat-provider-overview"
version = "0.1.0"
name = "deltachat-provider-database"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -551,10 +550,10 @@ dependencies = [
[[package]]
name = "deltachat_ffi"
version = "1.0.0-alpha.4"
version = "1.0.0-alpha.5"
dependencies = [
"deltachat 1.0.0-alpha.4",
"deltachat-provider-overview 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"deltachat 1.0.0-alpha.5",
"deltachat-provider-database 0.2.1 (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.62 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -687,7 +686,7 @@ name = "error-chain"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -704,7 +703,7 @@ name = "failure"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -780,7 +779,7 @@ name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -901,7 +900,7 @@ name = "human-panic"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (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.101 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1089,7 +1088,7 @@ dependencies = [
[[package]]
name = "lexical-core"
version = "0.4.5"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1300,7 +1299,7 @@ name = "nix"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.45 (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.62 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1326,7 +1325,7 @@ name = "nom"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lexical-core 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lexical-core 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1409,7 +1408,7 @@ name = "openssl"
version = "0.10.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1601,46 +1600,6 @@ dependencies = [
"x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf"
version = "0.7.24"
source = "git+https://github.com/sfackler/rust-phf?rev=0d00821#0d0082178568036736bb6d51cb91f95ca5a616c3"
dependencies = [
"phf_macros 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)",
"phf_shared 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)",
"proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_generator"
version = "0.7.24"
source = "git+https://github.com/sfackler/rust-phf?rev=0d00821#0d0082178568036736bb6d51cb91f95ca5a616c3"
dependencies = [
"phf_shared 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_macros"
version = "0.7.24"
source = "git+https://github.com/sfackler/rust-phf?rev=0d00821#0d0082178568036736bb6d51cb91f95ca5a616c3"
dependencies = [
"phf_generator 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)",
"phf_shared 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)",
"proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_shared"
version = "0.7.24"
source = "git+https://github.com/sfackler/rust-phf?rev=0d00821#0d0082178568036736bb6d51cb91f95ca5a616c3"
dependencies = [
"siphasher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pkg-config"
version = "0.3.16"
@@ -1657,7 +1616,7 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ctor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"ctor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1672,16 +1631,6 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.3 (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.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.4.30"
@@ -1692,7 +1641,7 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1704,7 +1653,7 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1734,7 +1683,7 @@ name = "pulldown-cmark"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1772,7 +1721,7 @@ name = "quote"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1835,7 +1784,6 @@ dependencies = [
"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)",
"rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1933,15 +1881,6 @@ dependencies = [
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_pcg"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_xorshift"
version = "0.1.1"
@@ -2063,7 +2002,7 @@ name = "rusqlite"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fallible-streaming-iterator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libsqlite3-sys 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2213,7 +2152,7 @@ name = "serde_derive"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.4 (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.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2273,11 +2212,6 @@ dependencies = [
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "siphasher"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "skeptic"
version = "0.13.4"
@@ -2355,7 +2289,7 @@ version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.4 (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.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2400,7 +2334,7 @@ name = "syn"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2926,13 +2860,13 @@ dependencies = [
"checksum ascii_utils 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a"
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
"checksum backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "5180c5a20655b14a819b652fd2378fa5f1697b6c9ddad3e695c2f9cedf6df4e2"
"checksum backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5"
"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
"checksum bitfield 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2"
"checksum blake2b_simd 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "5850aeee1552f495dd0250014cf64b82b7c8879a89d83b33bbdace2cc4f63182"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
@@ -2967,13 +2901,13 @@ dependencies = [
"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9"
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
"checksum ctor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5b6b2f4752cc29efbfd03474c532ce8f916f2d44ec5bb8c21f93bc76e5365528"
"checksum ctor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3e061727ebef83bbccac7c27b9a5ff9fd83094d34cb20f4005440a9562a27de7"
"checksum curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d"
"checksum darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfbcb0c5961907597a7d1148e3af036268f2b773886b8bb3eeb1e1281d3d3d6"
"checksum darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c"
"checksum darling_macro 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d8dac1c6f1d29a41c4712b4400f878cb4fcc4c7628f298dd75038e024998d1"
"checksum debug_stub_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "496b7f8a2f853313c3ca370641d7ff3e42c32974fdccda8f0684599ed0a3ff6b"
"checksum deltachat-provider-overview 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bef7b3626b0f859878db86ed54e4eef317adbcc3bcc3617eb38dec52e3f40e3"
"checksum deltachat-provider-database 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "814dba060d9fdc7a989fccdc4810ada9d1c7a1f09131c78e42412bc6c634b93b"
"checksum derive_builder 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ac53fa6a3cda160df823a9346442525dcaf1e171999a1cf23e67067e4fd64d4"
"checksum derive_builder_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0288a23da9333c246bb18c143426074a6ae96747995c5819d2947b64cd942b37"
"checksum derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839"
@@ -3035,7 +2969,7 @@ dependencies = [
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum lettre 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c66afaa5dfadbb81d4e00fd1d1ab057c7cd4c799c5a44e0009386d553587e728"
"checksum lexical-core 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d11f3928ffd249baadf9f083cdea16d7cf317b2a8be6227e1169102432a36d2"
"checksum lexical-core 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2304bccb228c4b020f3a4835d247df0a02a7c4686098d4167762cfbbe4c5cb14"
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
"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"
@@ -3086,17 +3020,12 @@ dependencies = [
"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.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bb80b37b7debf9a98dc0caca3ed40ddf1d383691208763d0458df0b91521020f"
"checksum phf 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)" = "<none>"
"checksum phf_generator 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)" = "<none>"
"checksum phf_macros 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)" = "<none>"
"checksum phf_shared 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)" = "<none>"
"checksum pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea"
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
"checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
"checksum pretty_env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "717ee476b1690853d222af4634056d830b5197ffd747726a9a1eee6da9f49074"
"checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8"
"checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc"
"checksum proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf147e022eacf0c8a054ab864914a7602618adba841d800a9a9868a5237a529f"
"checksum publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9bf259a81de2b2eb9850ec990ec78e6a25319715584fd7652b9b26f96fcb1510"
"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15"
@@ -3121,7 +3050,6 @@ dependencies = [
"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
"checksum rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e196346cbbc5c70c77e7b4926147ee8e383a38ee4d15d58a08098b169e492b6"
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
@@ -3156,7 +3084,6 @@ dependencies = [
"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"
"checksum sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf"
"checksum siphasher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9913c75df657d84a03fa689c016b0bb2863ff0b497b26a8d6e9703f8d5df03a8"
"checksum skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fb8ed853fdc19ce09752d63f3a2e5b5158aeb261520cd75eb618bd60305165"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum slice-deque 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ffddf594f5f597f63533d897427a570dbaa9feabaaa06595b74b71b7014507d7"

View File

@@ -1,6 +1,6 @@
[package]
name = "deltachat"
version = "1.0.0-alpha.4"
version = "1.0.0-alpha.5"
authors = ["dignifiedquire <dignifiedquire@gmail.com>"]
edition = "2018"
license = "MPL"
@@ -14,7 +14,6 @@ pgp = { version = "0.2", default-features = false }
hex = "0.3.2"
sha2 = "0.8.0"
rand = "0.6.5"
phf = { git = "https://github.com/sfackler/rust-phf", rev = "0d00821", features = ["macros"] }
smallvec = "0.6.9"
reqwest = "0.9.15"
num-derive = "0.2.5"

View File

@@ -1,6 +1,6 @@
[package]
name = "deltachat_ffi"
version = "1.0.0-alpha.4"
version = "1.0.0-alpha.5"
description = "Deltachat FFI"
authors = ["dignifiedquire <dignifiedquire@gmail.com>"]
edition = "2018"
@@ -16,7 +16,7 @@ crate-type = ["cdylib", "staticlib"]
[dependencies]
deltachat = { path = "../", default-features = false }
deltachat-provider-overview = "0.1.0"
deltachat-provider-database = "0.2.1"
libc = "0.2"
human-panic = "1.0.1"
num-traits = "0.2.6"

View File

@@ -405,9 +405,14 @@ char* dc_get_config (dc_context_t* context, const char*
/**
* Get information about the context.
*
* The information is returned by a multi-line string
* and contains information about the current configuration.
*
* If the context is not open or configured only a subset of the information
* will be available. There is no guarantee about which information will be
* included when however.
*
* @memberof dc_context_t
* @param context The context as created by dc_context_new().
* @return String which must be free()'d after usage. Never returns NULL.

View File

@@ -275,11 +275,11 @@ pub unsafe extern "C" fn dc_is_open(context: *mut dc_context_t) -> libc::c_int {
eprintln!("ignoring careless call to dc_is_open()");
return 0;
}
let ffi_context = &mut *context;
let ffi_context = &*context;
let inner_guard = ffi_context.inner.read().unwrap();
match *inner_guard {
Some(_) => 0,
None => 1,
Some(_) => 1,
None => 0,
}
}
@@ -347,9 +347,12 @@ pub unsafe extern "C" fn dc_get_info(context: *mut dc_context_t) -> *mut libc::c
return dc_strdup(ptr::null());
}
let ffi_context = &*context;
ffi_context
.with_inner(|ctx| render_info(ctx.get_info()).unwrap_or_default().strdup())
.unwrap_or_else(|_| "".strdup())
let guard = ffi_context.inner.read().unwrap();
let info = match guard.as_ref() {
Some(ref ctx) => ctx.get_info(),
None => context::get_info(),
};
render_info(info).unwrap_or_default().strdup()
}
fn render_info(
@@ -1519,7 +1522,7 @@ pub unsafe extern "C" fn dc_imex(
context: *mut dc_context_t,
what: libc::c_int,
param1: *mut libc::c_char,
param2: *mut libc::c_char,
_param2: *mut libc::c_char,
) {
if context.is_null() {
eprintln!("ignoring careless call to dc_imex()");
@@ -1527,7 +1530,7 @@ pub unsafe extern "C" fn dc_imex(
}
let ffi_context = &*context;
ffi_context
.with_inner(|ctx| dc_imex::dc_imex(ctx, what, as_opt_str(param1), param2))
.with_inner(|ctx| dc_imex::dc_imex(ctx, what, as_opt_str(param1)))
.ok();
}
@@ -1542,7 +1545,13 @@ pub unsafe extern "C" fn dc_imex_has_backup(
}
let ffi_context = &*context;
ffi_context
.with_inner(|ctx| dc_imex::dc_imex_has_backup(ctx, as_str(dir)))
.with_inner(|ctx| match dc_imex::dc_imex_has_backup(ctx, as_str(dir)) {
Ok(res) => res.strdup(),
Err(err) => {
error!(ctx, "dc_imex_has_backup: {}", err);
ptr::null_mut()
}
})
.unwrap_or_else(|_| ptr::null_mut())
}
@@ -1554,7 +1563,13 @@ pub unsafe extern "C" fn dc_initiate_key_transfer(context: *mut dc_context_t) ->
}
let ffi_context = &*context;
ffi_context
.with_inner(|ctx| dc_imex::dc_initiate_key_transfer(ctx))
.with_inner(|ctx| match dc_imex::dc_initiate_key_transfer(ctx) {
Ok(res) => res.strdup(),
Err(err) => {
error!(ctx, "dc_initiate_key_transfer(): {}", err);
ptr::null_mut()
}
})
.unwrap_or_else(|_| ptr::null_mut())
}
@@ -1573,7 +1588,15 @@ pub unsafe extern "C" fn dc_continue_key_transfer(
}
let ffi_context = &*context;
ffi_context
.with_inner(|ctx| dc_imex::dc_continue_key_transfer(ctx, msg_id, setup_code) as libc::c_int)
.with_inner(|ctx| {
match dc_imex::dc_continue_key_transfer(ctx, msg_id, as_str(setup_code)) {
Ok(()) => 1,
Err(err) => {
error!(ctx, "dc_continue_key_transfer: {}", err);
0
}
}
})
.unwrap_or(0)
}
@@ -2345,7 +2368,11 @@ pub unsafe extern "C" fn dc_msg_get_filemime(msg: *mut dc_msg_t) -> *mut libc::c
return dc_strdup(ptr::null());
}
let ffi_msg = &*msg;
ffi_msg.message.get_filemime().strdup()
if let Some(x) = ffi_msg.message.get_filemime() {
x.strdup()
} else {
return dc_strdup(ptr::null());
}
}
#[no_mangle]

View File

@@ -1,18 +1,18 @@
extern crate deltachat_provider_overview;
extern crate deltachat_provider_database;
use std::ptr;
use deltachat::dc_tools::{as_str, StrExt};
use deltachat_provider_overview::StatusState;
use deltachat_provider_database::StatusState;
#[no_mangle]
pub type dc_provider_t = deltachat_provider_overview::Provider;
pub type dc_provider_t = deltachat_provider_database::Provider;
#[no_mangle]
pub unsafe extern "C" fn dc_provider_new_from_domain(
domain: *const libc::c_char,
) -> *const dc_provider_t {
match deltachat_provider_overview::get_provider_info(as_str(domain)) {
match deltachat_provider_database::get_provider_info(as_str(domain)) {
Some(provider) => provider,
None => ptr::null(),
}
@@ -22,8 +22,8 @@ pub unsafe extern "C" fn dc_provider_new_from_domain(
pub unsafe extern "C" fn dc_provider_new_from_email(
email: *const libc::c_char,
) -> *const dc_provider_t {
let domain = deltachat_provider_overview::get_domain_from_email(as_str(email));
match deltachat_provider_overview::get_provider_info(domain) {
let domain = deltachat_provider_database::get_domain_from_email(as_str(email));
match deltachat_provider_database::get_provider_info(domain) {
Some(provider) => provider,
None => ptr::null(),
}
@@ -44,7 +44,7 @@ pub unsafe extern "C" fn dc_provider_get_overview_page(
null_guard!(provider);
format!(
"{}/{}",
deltachat_provider_overview::PROVIDER_OVERVIEW_URL,
deltachat_provider_database::PROVIDER_OVERVIEW_URL,
(*provider).overview_page
)
.strdup()

View File

@@ -1,5 +1,4 @@
use std::path::Path;
use std::ptr;
use std::str::FromStr;
use deltachat::chat::{self, Chat};
@@ -97,16 +96,7 @@ pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 {
fn dc_poke_eml_file(context: &Context, filename: impl AsRef<Path>) -> Result<(), Error> {
let data = dc_read_file(context, filename)?;
unsafe {
dc_receive_imf(
context,
data.as_ptr() as *const _,
data.len(),
"import",
0,
0,
)
};
unsafe { dc_receive_imf(context, &data, "import", 0, 0) };
Ok(())
}
@@ -327,12 +317,8 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
arg1.strdup() as *const _
};
let arg2 = args.next().unwrap_or_default();
let arg2_c = if arg2.is_empty() {
std::ptr::null()
} else {
arg2.strdup() as *const _
};
let blobdir = context.get_blobdir();
match arg0 {
"help" | "?" => match arg1 {
// TODO: reuse commands definition in main.rs.
@@ -419,18 +405,13 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
============================================="
),
},
"initiate-key-transfer" => {
let setup_code = dc_initiate_key_transfer(context);
if !setup_code.is_null() {
println!(
"Setup code for the transferred setup message: {}",
as_str(setup_code),
);
free(setup_code as *mut libc::c_void);
} else {
bail!("Failed to generate setup code");
};
}
"initiate-key-transfer" => match dc_initiate_key_transfer(context) {
Ok(setup_code) => println!(
"Setup code for the transferred setup message: {}",
setup_code,
),
Err(err) => bail!("Failed to generate setup code: {}", err),
},
"get-setupcodebegin" => {
ensure!(!arg1.is_empty(), "Argument <msg-id> missing.");
let msg_id: u32 = arg1.parse()?;
@@ -451,32 +432,27 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
!arg1.is_empty() && !arg2.is_empty(),
"Arguments <msg-id> <setup-code> expected"
);
if !dc_continue_key_transfer(context, arg1.parse()?, arg2_c) {
bail!("Continue key transfer failed");
}
dc_continue_key_transfer(context, arg1.parse()?, &arg2)?;
}
"has-backup" => {
let ret = dc_imex_has_backup(context, context.get_blobdir());
if ret.is_null() {
println!("No backup found.");
}
dc_imex_has_backup(context, blobdir)?;
}
"export-backup" => {
dc_imex(context, 11, Some(context.get_blobdir()), ptr::null());
dc_imex(context, 11, Some(blobdir));
}
"import-backup" => {
ensure!(!arg1.is_empty(), "Argument <backup-file> missing.");
dc_imex(context, 12, Some(arg1), ptr::null());
dc_imex(context, 12, Some(arg1));
}
"export-keys" => {
dc_imex(context, 1, Some(context.get_blobdir()), ptr::null());
dc_imex(context, 1, Some(blobdir));
}
"import-keys" => {
dc_imex(context, 2, Some(context.get_blobdir()), ptr::null());
dc_imex(context, 2, Some(blobdir));
}
"export-setup" => {
let setup_code = dc_create_setup_code(context);
let file_name = context.get_blobdir().join("autocrypt-setup-message.html");
let file_name = blobdir.join("autocrypt-setup-message.html");
let file_content = dc_render_setup_file(context, &setup_code)?;
std::fs::write(&file_name, file_content)?;
println!(
@@ -1001,7 +977,6 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
}
free(arg1_c as *mut _);
free(arg2_c as *mut _);
Ok(())
}

71
mmime/src/constants.rs Normal file
View File

@@ -0,0 +1,71 @@
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;

View File

@@ -20,17 +20,7 @@ pub mod charconv;
pub mod chash;
pub mod clist;
pub mod mailimf;
pub mod mailimf_types;
pub mod mailimf_types_helper;
pub mod mailimf_write_generic;
pub mod mailmime;
pub mod mailmime_content;
pub mod mailmime_decode;
pub mod mailmime_disposition;
pub mod mailmime_types;
pub mod mailmime_types_helper;
pub mod mailmime_write_generic;
pub mod mailmime_write_mem;
pub mod mmapstring;
pub mod other;
@@ -38,24 +28,16 @@ pub use self::charconv::*;
pub use self::chash::*;
pub use self::clist::*;
pub use self::mailimf::*;
pub use self::mailimf_types::*;
pub use self::mailimf_types_helper::*;
pub use self::mailimf_write_generic::*;
pub use self::mailmime::*;
pub use self::mailmime_content::*;
pub use self::mailmime_decode::*;
pub use self::mailmime_disposition::*;
pub use self::mailmime_types::*;
pub use self::mailmime_types_helper::*;
pub use self::mailmime_write_generic::*;
pub use self::mailmime_write_mem::*;
pub use self::mmapstring::*;
pub use self::other::*;
#[cfg(test)]
mod tests {
use super::*;
use crate::mailmime_types::{mailmime, mailmime_content, mailmime_disposition};
use crate::mailimf::types::*;
use crate::mailmime::types::*;
use std::ffi::CStr;
#[test]
@@ -80,7 +62,7 @@ mod tests {
let mut current_index = 0;
let mut mime = std::ptr::null_mut();
let res = crate::mailmime_content::mailmime_parse(
let res = crate::mailmime::content::mailmime_parse(
c_data.as_ptr(),
data.len() as usize,
&mut current_index,
@@ -92,11 +74,11 @@ mod tests {
display_mime(mime);
mailmime_types::mailmime_free(mime);
mailmime::types::mailmime_free(mime);
}
}
unsafe fn display_mime(mut mime: *mut mailmime) {
unsafe fn display_mime(mut mime: *mut Mailmime) {
let mut cur: *mut clistiter = 0 as *mut clistiter;
println!("{}", (*mime).mm_type);
@@ -130,7 +112,7 @@ mod tests {
(*cur).data
} else {
0 as *mut libc::c_void
}) as *mut mailmime,
}) as *mut Mailmime,
);
cur = if !cur.is_null() {
(*cur).next

View File

@@ -1,10 +1,13 @@
use libc;
use libc::toupper;
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::mailimf::types::*;
use crate::mailmime::decode::*;
use crate::mailmime::types::*;
use crate::mmapstring::*;
use crate::other::*;

View File

@@ -43,15 +43,14 @@ pub struct mailimf_date_time {
pub dt_zone: libc::c_int,
}
/* this is the type of address */
pub type unnamed = libc::c_uint;
/* if this is a group
(group_name: address1@domain1,
address2@domain2; ) */
pub const MAILIMF_ADDRESS_GROUP: unnamed = 2;
pub const MAILIMF_ADDRESS_GROUP: libc::c_uint = 2;
/* if this is a mailbox (mailbox@domain) */
pub const MAILIMF_ADDRESS_MAILBOX: unnamed = 1;
pub const MAILIMF_ADDRESS_MAILBOX: libc::c_uint = 1;
/* on parse error */
pub const MAILIMF_ADDRESS_ERROR: unnamed = 0;
pub const MAILIMF_ADDRESS_ERROR: libc::c_uint = 0;
/*
mailimf_address is an address

View File

@@ -1,5 +1,5 @@
use crate::clist::*;
use crate::mailimf_types::*;
use crate::mailimf::types::*;
use crate::other::*;
/*

View File

@@ -1,5 +1,5 @@
use crate::clist::*;
use crate::mailimf_types::*;
use crate::mailimf::types::*;
use crate::other::*;
pub const STATE_WORD: libc::c_uint = 1;
@@ -1983,43 +1983,3 @@ unsafe fn mailimf_path_write_driver(
}
return MAILIMF_NO_ERROR as libc::c_int;
}
/*
mailimf_envelope_fields_write writes only some 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_envelope_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;
let mut field: *mut mailimf_field = 0 as *mut mailimf_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 = mailimf_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;
}

View File

@@ -1,9 +1,9 @@
use crate::clist::*;
use crate::mailimf::types::*;
use crate::mailimf::*;
use crate::mailimf_types::*;
use crate::mailmime::types::*;
use crate::mailmime::types_helper::*;
use crate::mailmime::*;
use crate::mailmime_types::*;
use crate::mailmime_types_helper::*;
use crate::mmapstring::*;
use crate::other::*;
@@ -80,9 +80,9 @@ 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,
mut result: *mut *mut Mailmime,
) -> libc::c_int {
let mut 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 content_message: *mut mailmime_content = 0 as *mut mailmime_content;
@@ -174,7 +174,7 @@ unsafe fn mailmime_parse_with_default(
mut default_type: libc::c_int,
mut content_type: *mut mailmime_content,
mut mime_fields: *mut mailmime_fields,
mut result: *mut *mut mailmime,
mut result: *mut *mut Mailmime,
) -> libc::c_int {
let mut current_block: u64;
let mut cur_token: size_t = 0;
@@ -184,8 +184,8 @@ unsafe fn mailmime_parse_with_default(
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 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;
@@ -312,7 +312,7 @@ unsafe fn mailmime_parse_with_default(
res = MAILIMF_ERROR_MEMORY as libc::c_int
} else {
list = 0 as *mut clist;
msg_mime = 0 as *mut mailmime;
msg_mime = 0 as *mut Mailmime;
fields = 0 as *mut mailimf_fields;
match body_type {
3 => {
@@ -361,7 +361,7 @@ unsafe fn mailmime_parse_with_default(
current_block = 12065775993741208975;
} else if r == MAILIMF_ERROR_PARSE as libc::c_int {
mailmime_fields_free(mime_fields);
msg_mime = 0 as *mut mailmime;
msg_mime = 0 as *mut Mailmime;
current_block = 12065775993741208975;
} else {
mailmime_fields_free(mime_fields);
@@ -456,7 +456,7 @@ unsafe fn mailmime_parse_with_default(
clist_foreach(
list,
::std::mem::transmute::<
Option<unsafe fn(_: *mut mailmime) -> ()>,
Option<unsafe fn(_: *mut Mailmime) -> ()>,
clist_func,
>(Some(
mailmime_free,
@@ -605,7 +605,7 @@ unsafe fn mailmime_multipart_body_parse(
break;
}
let mut bp_token: size_t = 0;
let mut mime_bp: *mut mailmime = 0 as *mut mailmime;
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;
@@ -821,7 +821,7 @@ unsafe fn mailmime_multipart_body_parse(
clist_foreach(
list,
::std::mem::transmute::<
Option<unsafe fn(_: *mut mailmime) -> ()>,
Option<unsafe fn(_: *mut Mailmime) -> ()>,
clist_func,
>(Some(mailmime_free)),
0 as *mut libc::c_void,
@@ -1344,20 +1344,20 @@ pub unsafe fn mailmime_extract_boundary(
}
pub unsafe fn mailmime_get_section(
mut mime: *mut mailmime,
mut mime: *mut Mailmime,
mut section: *mut mailmime_section,
mut result: *mut *mut mailmime,
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 mime: *mut Mailmime,
mut list: *mut clistiter,
mut result: *mut *mut mailmime,
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;
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;
@@ -1367,14 +1367,14 @@ unsafe fn mailmime_get_section_list(
} else {
0 as *mut libc::c_void
}) as *mut uint32_t);
data = 0 as *mut mailmime;
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;
) as *mut Mailmime;
if data.is_null() {
return MAILIMF_ERROR_INVAL as libc::c_int;
}
@@ -1406,7 +1406,7 @@ unsafe fn mailmime_get_section_list(
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;
) as *mut Mailmime;
if data.is_null() {
return MAILIMF_ERROR_INVAL as libc::c_int;
}
@@ -2147,7 +2147,7 @@ pub unsafe fn mailmime_part_parse_partial(
}
pub unsafe fn mailmime_get_section_id(
mut mime: *mut mailmime,
mut mime: *mut Mailmime,
mut result: *mut *mut mailmime_section,
) -> libc::c_int {
let mut current_block: u64;
@@ -2173,7 +2173,7 @@ pub unsafe fn mailmime_get_section_id(
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;
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;

View File

@@ -3,14 +3,11 @@ use libc::toupper;
use crate::charconv::*;
use crate::mailimf::*;
use crate::mailmime_content::*;
use crate::mailmime_types::*;
use crate::mailmime::content::*;
use crate::mailmime::types::*;
use crate::mmapstring::*;
use crate::other::*;
pub const MAIL_CHARCONV_ERROR_CONV: libc::c_uint = 3;
pub const MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET: libc::c_uint = 1;
pub const MAIL_CHARCONV_ERROR_MEMORY: libc::c_uint = 2;
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;
@@ -850,7 +847,7 @@ unsafe fn mailmime_etoken_parse(
return mailimf_custom_string_parse(message, length, indx, result, Some(is_etoken_char));
}
pub unsafe fn is_etoken_char(mut ch: libc::c_char) -> libc::c_int {
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;

View File

@@ -1,10 +1,9 @@
use libc;
use libc::toupper;
use libc::{self, toupper};
use crate::clist::*;
use crate::mailimf::*;
use crate::mailmime::types::*;
use crate::mailmime::*;
use crate::mailmime_types::*;
use crate::other::*;
pub const MAILMIME_DISPOSITION_TYPE_EXTENSION: libc::c_uint = 3;

View File

@@ -1,13 +1,19 @@
use libc;
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::mailimf_types::*;
use crate::mailmime_decode::*;
use crate::mailmime_disposition::*;
use crate::mailmime_types::*;
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;

View File

@@ -1,7 +1,5 @@
use libc;
use crate::clist::*;
use crate::mailimf_types::*;
use crate::mailimf::types::*;
use crate::mmapstring::*;
use crate::other::*;
@@ -164,9 +162,9 @@ pub const MAILMIME_NONE: unnamed_7 = 0;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailmime {
pub struct Mailmime {
pub mm_parent_type: libc::c_int,
pub mm_parent: *mut mailmime,
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,
@@ -188,7 +186,7 @@ pub union unnamed_8 {
#[repr(C)]
pub struct unnamed_9 {
pub mm_fields: *mut mailimf_fields,
pub mm_msg_mime: *mut mailmime,
pub mm_msg_mime: *mut Mailmime,
}
/* multi-part */
#[derive(Copy, Clone)]
@@ -656,15 +654,15 @@ pub unsafe fn mailmime_new(
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;
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::<mailmime>() as libc::size_t) as *mut mailmime;
mime = malloc(::std::mem::size_of::<Mailmime>() as libc::size_t) as *mut Mailmime;
if mime.is_null() {
return 0 as *mut mailmime;
return 0 as *mut Mailmime;
}
(*mime).mm_parent = 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;
@@ -681,12 +679,12 @@ pub unsafe fn mailmime_new(
(*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;
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;
}) as *mut Mailmime;
(*submime).mm_parent = mime;
(*submime).mm_parent_type = MAILMIME_MULTIPLE as libc::c_int;
(*submime).mm_multipart_pos = cur;
@@ -710,7 +708,7 @@ pub unsafe fn mailmime_new(
return mime;
}
pub unsafe fn mailmime_free(mut mime: *mut mailmime) {
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() {
@@ -727,7 +725,7 @@ pub unsafe fn mailmime_free(mut mime: *mut mailmime) {
}
clist_foreach(
(*mime).mm_data.mm_multipart.mm_mp_list,
::std::mem::transmute::<Option<unsafe fn(_: *mut mailmime) -> ()>, clist_func>(
::std::mem::transmute::<Option<unsafe fn(_: *mut Mailmime) -> ()>, clist_func>(
Some(mailmime_free),
),
0 as *mut libc::c_void,

View File

@@ -1,10 +1,9 @@
use libc;
use rand::{thread_rng, Rng};
use crate::clist::*;
use crate::mailimf_types::*;
use crate::mailimf::types::*;
use crate::mailmime::types::*;
use crate::mailmime::*;
use crate::mailmime_types::*;
use crate::other::*;
#[derive(Copy, Clone)]
@@ -637,9 +636,9 @@ pub unsafe fn mailmime_data_new_file(
);
}
pub unsafe fn mailmime_new_message_data(mut msg_mime: *mut mailmime) -> *mut mailmime {
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 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() {
@@ -672,15 +671,15 @@ pub unsafe fn mailmime_new_message_data(mut msg_mime: *mut mailmime) -> *mut mai
}
mailmime_content_free(content);
}
return 0 as *mut mailmime;
return 0 as *mut Mailmime;
}
pub unsafe fn mailmime_new_empty(
mut content: *mut mailmime_content,
mut mime_fields: *mut mailmime_fields,
) -> *mut mailmime {
) -> *mut Mailmime {
let mut current_block: u64;
let mut build_info: *mut mailmime = 0 as *mut mailmime;
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;
@@ -823,11 +822,11 @@ pub unsafe fn mailmime_new_empty(
0 as *mut mailmime_data,
list,
0 as *mut mailimf_fields,
0 as *mut mailmime,
0 as *mut Mailmime,
);
if build_info.is_null() {
clist_free(list);
return 0 as *mut mailmime;
return 0 as *mut Mailmime;
}
return build_info;
}
@@ -835,7 +834,7 @@ pub unsafe fn mailmime_new_empty(
}
_ => {}
}
return 0 as *mut mailmime;
return 0 as *mut Mailmime;
}
pub unsafe fn mailmime_generate_boundary() -> *mut libc::c_char {
@@ -856,12 +855,12 @@ pub unsafe fn mailmime_generate_boundary() -> *mut libc::c_char {
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,
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 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(
@@ -886,7 +885,7 @@ pub unsafe fn mailmime_new_with_content(
}
pub unsafe fn mailmime_set_preamble_file(
mut build_info: *mut mailmime,
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;
@@ -906,7 +905,7 @@ pub unsafe fn mailmime_set_preamble_file(
}
pub unsafe fn mailmime_set_epilogue_file(
mut build_info: *mut mailmime,
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;
@@ -926,7 +925,7 @@ pub unsafe fn mailmime_set_epilogue_file(
}
pub unsafe fn mailmime_set_preamble_text(
mut build_info: *mut mailmime,
mut build_info: *mut Mailmime,
mut data_str: *mut libc::c_char,
mut length: size_t,
) -> libc::c_int {
@@ -947,7 +946,7 @@ pub unsafe fn mailmime_set_preamble_text(
}
pub unsafe fn mailmime_set_epilogue_text(
mut build_info: *mut mailmime,
mut build_info: *mut Mailmime,
mut data_str: *mut libc::c_char,
mut length: size_t,
) -> libc::c_int {
@@ -968,7 +967,7 @@ pub unsafe fn mailmime_set_epilogue_text(
}
pub unsafe fn mailmime_set_body_file(
mut build_info: *mut mailmime,
mut build_info: *mut Mailmime,
mut filename: *mut libc::c_char,
) -> libc::c_int {
let mut encoding: libc::c_int = 0;
@@ -990,7 +989,7 @@ pub unsafe fn mailmime_set_body_file(
}
pub unsafe fn mailmime_set_body_text(
mut build_info: *mut mailmime,
mut build_info: *mut Mailmime,
mut data_str: *mut libc::c_char,
mut length: size_t,
) -> libc::c_int {
@@ -1013,8 +1012,8 @@ pub unsafe fn mailmime_set_body_text(
}
pub unsafe fn mailmime_add_part(
mut build_info: *mut mailmime,
mut part: *mut mailmime,
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 {
@@ -1039,19 +1038,19 @@ pub unsafe fn mailmime_add_part(
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;
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
(*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;
(*mime).mm_parent = 0 as *mut Mailmime;
clist_delete(
(*parent).mm_data.mm_multipart.mm_mp_list,
(*mime).mm_multipart_pos,
@@ -1062,7 +1061,7 @@ pub unsafe fn mailmime_remove_part(mut mime: *mut mailmime) {
}
pub unsafe fn mailmime_set_imf_fields(
mut build_info: *mut mailmime,
mut build_info: *mut Mailmime,
mut mm_fields: *mut mailimf_fields,
) {
(*build_info).mm_data.mm_message.mm_fields = mm_fields;
@@ -1213,11 +1212,11 @@ pub unsafe fn mailmime_single_fields_free(mut single_fields: *mut mailmime_singl
}
pub unsafe fn mailmime_smart_add_part(
mut mime: *mut mailmime,
mut mime_sub: *mut mailmime,
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 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 {
@@ -1278,10 +1277,10 @@ pub unsafe fn mailmime_smart_add_part(
return res;
}
pub unsafe fn mailmime_multiple_new(mut type_0: *const libc::c_char) -> *mut mailmime {
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;
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);
@@ -1295,7 +1294,7 @@ pub unsafe fn mailmime_multiple_new(mut type_0: *const libc::c_char) -> *mut mai
}
mailmime_fields_free(mime_fields);
}
return 0 as *mut mailmime;
return 0 as *mut Mailmime;
}
pub unsafe fn mailmime_content_new_with_str(mut str: *const libc::c_char) -> *mut mailmime_content {
@@ -1310,8 +1309,8 @@ pub unsafe fn mailmime_content_new_with_str(mut str: *const libc::c_char) -> *mu
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;
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() {

View File

@@ -1,11 +1,11 @@
use std::ffi::CStr;
use crate::clist::*;
use crate::mailimf_write_generic::*;
use crate::mailimf::write_generic::*;
use crate::mailmime::content::*;
use crate::mailmime::types::*;
use crate::mailmime::types_helper::*;
use crate::mailmime::*;
use crate::mailmime_content::*;
use crate::mailmime_types::*;
use crate::mailmime_types_helper::*;
use crate::other::*;
pub const STATE_INIT: libc::c_uint = 0;
@@ -1017,7 +1017,7 @@ pub unsafe fn mailmime_write_driver(
>,
mut data: *mut libc::c_void,
mut col: *mut libc::c_int,
mut build_info: *mut mailmime,
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);
@@ -1038,7 +1038,7 @@ unsafe fn mailmime_part_write_driver(
>,
mut data: *mut libc::c_void,
mut col: *mut libc::c_int,
mut build_info: *mut mailmime,
mut build_info: *mut Mailmime,
) -> libc::c_int {
let mut current_block: u64;
let mut cur: *mut clistiter = 0 as *mut clistiter;
@@ -1152,8 +1152,8 @@ unsafe fn mailmime_part_write_driver(
current_block = 3546145585875536353;
break;
}
let mut subpart: *mut mailmime = 0 as *mut mailmime;
subpart = (*cur).data as *mut mailmime;
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,
@@ -1421,7 +1421,7 @@ unsafe fn mailmime_sub_write_driver(
>,
mut data: *mut libc::c_void,
mut col: *mut libc::c_int,
mut build_info: *mut mailmime,
mut build_info: *mut Mailmime,
) -> libc::c_int {
let mut r: libc::c_int = 0;
if !(*build_info).mm_content_type.is_null() {

View File

@@ -1,5 +1,5 @@
use crate::mailmime_types::*;
use crate::mailmime_write_generic::*;
use crate::mailmime::types::*;
use crate::mailmime::write_generic::*;
use crate::mmapstring::*;
use crate::other::*;
@@ -41,7 +41,7 @@ pub unsafe fn mailmime_content_type_write_mem(
pub unsafe fn mailmime_write_mem(
mut f: *mut MMAPString,
mut col: *mut libc::c_int,
mut build_info: *mut mailmime,
mut build_info: *mut Mailmime,
) -> libc::c_int {
return mailmime_write_driver(Some(do_write), f as *mut libc::c_void, col, build_info);
}

View File

@@ -1,10 +1,10 @@
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::*;
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,
@@ -132,7 +132,7 @@ 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) {
pub unsafe fn mailprivacy_prepare_mime(mut mime: *mut Mailmime) {
let mut cur: *mut clistiter = 0 as *mut clistiter;
match (*mime).mm_type {
1 => {
@@ -143,12 +143,12 @@ pub unsafe fn mailprivacy_prepare_mime(mut mime: *mut mailmime) {
2 => {
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
while !cur.is_null() {
let mut child: *mut mailmime = 0 as *mut mailmime;
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;
}) as *mut Mailmime;
mailprivacy_prepare_mime(child);
cur = if !cur.is_null() {
(*cur).next
@@ -166,7 +166,7 @@ pub unsafe fn mailprivacy_prepare_mime(mut mime: *mut mailmime) {
};
}
unsafe fn prepare_mime_single(mut mime: *mut mailmime) {
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,
@@ -251,10 +251,10 @@ unsafe fn prepare_mime_single(mut mime: *mut mailmime) {
}
pub unsafe fn mailmime_substitute(
mut old_mime: *mut mailmime,
mut new_mime: *mut mailmime,
mut old_mime: *mut Mailmime,
mut new_mime: *mut Mailmime,
) -> libc::c_int {
let mut parent: *mut mailmime = 0 as *mut mailmime;
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;
@@ -266,7 +266,7 @@ pub unsafe fn mailmime_substitute(
}
(*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 = 0 as *mut Mailmime;
(*old_mime).mm_parent_type = MAILMIME_NONE as libc::c_int;
return MAIL_NO_ERROR as libc::c_int;
}

View File

@@ -5,3 +5,4 @@
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 679506fe9ac59df773f8cfa800fdab5f0a32fe49d2ab370394000a1aa5bc2a72 # shrinks to buf = "%0A"
cc e34960438edb2426904b44fb4215154e7e2880f2fd1c3183b98bfcc76fec4882 # shrinks to input = " 0"

View File

@@ -6,7 +6,7 @@
import os
import subprocess
import os
import sys
if __name__ == "__main__":
os.environ["DCC_RS_TARGET"] = target = "release"
@@ -21,5 +21,5 @@ if __name__ == "__main__":
subprocess.check_call("rm -rf build/ src/deltachat/*.so" , shell=True)
subprocess.check_call([
"pip", "install", "-e", "."
sys.executable, "-m", "pip", "install", "-e", "."
])

View File

@@ -2,7 +2,6 @@
from __future__ import print_function
import threading
import os
import re
import time
from array import array
@@ -23,7 +22,7 @@ class Account(object):
by the underlying deltachat c-library. All public Account methods are
meant to be memory-safe and return memory-safe objects.
"""
def __init__(self, db_path, logid=None, eventlogging=True):
def __init__(self, db_path, logid=None, eventlogging=True, debug=True):
""" initialize account object.
:param db_path: a path to the account database. The database
@@ -31,13 +30,14 @@ class Account(object):
:param logid: an optional logging prefix that should be used with
the default internal logging.
:param eventlogging: if False no eventlogging and no context callback will be configured
:param debug: turn on debug logging for events.
"""
self._dc_context = ffi.gc(
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
_destroy_dc_context,
)
if eventlogging:
self._evlogger = EventLogger(self._dc_context, logid)
self._evlogger = EventLogger(self._dc_context, logid, debug)
deltachat.set_context_callback(self._dc_context, self._process_event)
self._threads = IOThreads(self._dc_context, self._evlogger._log_event)
else:
@@ -48,7 +48,7 @@ class Account(object):
if not lib.dc_open(self._dc_context, db_path, ffi.NULL):
raise ValueError("Could not dc_open: {}".format(db_path))
self._configkeys = self.get_config("sys.config_keys").split()
self._imex_completed = threading.Event()
self._imex_events = Queue()
def __del__(self):
self.shutdown()
@@ -289,31 +289,64 @@ class Account(object):
msg_ids = [msg.id for msg in messages]
lib.dc_delete_msgs(self._dc_context, msg_ids, len(msg_ids))
def export_to_dir(self, backupdir):
"""return after all delta chat state is exported to a new file in
the specified directory.
def export_self_keys(self, path):
""" export public and private keys to the specified directory. """
return self._export(path, imex_cmd=1)
def export_all(self, path):
"""return new file containing a backup of all database state
(chats, contacts, keys, media, ...). The file is created in the
the `path` directory.
"""
snap_files = os.listdir(backupdir)
self._imex_completed.clear()
lib.dc_imex(self._dc_context, 11, as_dc_charpointer(backupdir), ffi.NULL)
export_files = self._export(path, 11)
if len(export_files) != 1:
raise RuntimeError("found more than one new file")
return export_files[0]
def _imex_events_clear(self):
try:
while True:
self._imex_events.get_nowait()
except Empty:
pass
def _export(self, path, imex_cmd):
self._imex_events_clear()
lib.dc_imex(self._dc_context, imex_cmd, as_dc_charpointer(path), ffi.NULL)
if not self._threads.is_started():
lib.dc_perform_imap_jobs(self._dc_context)
self._imex_completed.wait()
for x in os.listdir(backupdir):
if x not in snap_files:
return os.path.join(backupdir, x)
files_written = []
while True:
ev = self._imex_events.get()
if isinstance(ev, str):
files_written.append(ev)
elif isinstance(ev, bool):
if not ev:
raise ValueError("export failed, exp-files: {}".format(files_written))
return files_written
def import_from_file(self, path):
"""import delta chat state from the specified backup file.
def import_self_keys(self, path):
""" Import private keys found in the `path` directory.
The last imported key is made the default keys unless its name
contains the string legacy. Public keys are not imported.
"""
self._import(path, imex_cmd=2)
def import_all(self, path):
"""import delta chat state from the specified backup `path` (a file).
The account must be in unconfigured state for import to attempted.
"""
assert not self.is_configured(), "cannot import into configured account"
self._imex_completed.clear()
lib.dc_imex(self._dc_context, 12, as_dc_charpointer(path), ffi.NULL)
self._import(path, imex_cmd=12)
def _import(self, path, imex_cmd):
self._imex_events_clear()
lib.dc_imex(self._dc_context, imex_cmd, as_dc_charpointer(path), ffi.NULL)
if not self._threads.is_started():
lib.dc_perform_imap_jobs(self._dc_context)
self._imex_completed.wait()
if not self._imex_events.get():
raise ValueError("import from path '{}' failed".format(path))
def initiate_key_transfer(self):
"""return setup code after a Autocrypt setup message
@@ -423,7 +456,12 @@ class Account(object):
def on_dc_event_imex_progress(self, data1, data2):
if data1 == 1000:
self._imex_completed.set()
self._imex_events.put(True)
elif data1 == 0:
self._imex_events.put(False)
def on_dc_event_imex_file_written(self, data1, data2):
self._imex_events.put(data1)
class IOThreads:

View File

@@ -101,6 +101,10 @@ class Message(object):
""" return True if this message is a setup message. """
return lib.dc_msg_is_setupmessage(self._dc_msg)
def get_setupcodebegin(self):
""" return the first characters of a setup code in a setup message. """
return from_dc_charpointer(lib.dc_msg_get_setupcodebegin(self._dc_msg))
def is_encrypted(self):
""" return True if this message was encrypted. """
return bool(lib.dc_msg_get_showpadlock(self._dc_msg))

View File

@@ -93,8 +93,9 @@ class TestOfflineContact:
ac1 = acfactory.get_configured_offline_account()
contact1 = ac1.create_contact(email="some1@example.com", name="some1")
chat = ac1.create_chat_by_contact(contact1)
chat.send_text("one messae")
msg = chat.send_text("one messae")
assert not ac1.delete_contact(contact1)
assert not msg.filemime
class TestOfflineChat:
@@ -293,10 +294,10 @@ class TestOfflineChat:
assert contact == ac1.get_self_contact()
assert not backupdir.listdir()
path = ac1.export_to_dir(backupdir.strpath)
path = ac1.export_all(backupdir.strpath)
assert os.path.exists(path)
ac2 = acfactory.get_unconfigured_account()
ac2.import_from_file(path)
ac2.import_all(path)
contacts = ac2.get_contacts(query="some1")
assert len(contacts) == 1
contact2 = contacts[0]
@@ -340,6 +341,16 @@ class TestOnlineAccount:
assert chat.id > const.DC_CHAT_ID_LAST_SPECIAL
return chat
def test_export_import_self_keys(self, acfactory, tmpdir):
ac1, ac2 = acfactory.get_two_online_accounts()
dir = tmpdir.mkdir("exportdir")
export_files = ac1.export_self_keys(dir.strpath)
assert len(export_files) == 2
for x in export_files:
assert x.startswith(dir.strpath)
ac1._evlogger.consume_events()
ac1.import_self_keys(dir.strpath)
def test_one_account_send(self, acfactory):
ac1 = acfactory.get_online_configuring_account()
c2 = ac1.create_contact(email=ac1.get_config("addr"))
@@ -501,7 +512,7 @@ class TestOnlineAccount:
assert os.path.exists(msg_in.filename)
assert os.stat(msg_in.filename).st_size == os.stat(path).st_size
def test_import_export_online(self, acfactory, tmpdir):
def test_import_export_online_all(self, acfactory, tmpdir):
ac1 = acfactory.get_online_configuring_account()
wait_configuration_progress(ac1, 1000)
@@ -509,11 +520,11 @@ class TestOnlineAccount:
chat = ac1.create_chat_by_contact(contact1)
chat.send_text("msg1")
backupdir = tmpdir.mkdir("backup")
path = ac1.export_to_dir(backupdir.strpath)
path = ac1.export_all(backupdir.strpath)
assert os.path.exists(path)
ac2 = acfactory.get_unconfigured_account()
ac2.import_from_file(path)
ac2.import_all(path)
contacts = ac2.get_contacts(query="some1")
assert len(contacts) == 1
contact2 = contacts[0]
@@ -523,7 +534,7 @@ class TestOnlineAccount:
assert len(messages) == 1
assert messages[0].text == "msg1"
def test_ac_setup_message(self, acfactory):
def test_ac_setup_message(self, acfactory, lp):
# note that the receiving account needs to be configured and running
# before ther setup message is send. DC does not read old messages
# as of Jul2019
@@ -531,15 +542,18 @@ class TestOnlineAccount:
ac2 = acfactory.clone_online_account(ac1)
wait_configuration_progress(ac2, 1000)
wait_configuration_progress(ac1, 1000)
lp.sec("trigger ac setup message and return setupcode")
assert ac1.get_info()["fingerprint"] != ac2.get_info()["fingerprint"]
setup_code = ac1.initiate_key_transfer()
ac2._evlogger.set_timeout(30)
ev = ac2._evlogger.get_matching("DC_EVENT_INCOMING_MSG|DC_EVENT_MSGS_CHANGED")
msg = ac2.get_message_by_id(ev[2])
assert msg.is_setup_message()
# first try a bad setup code
assert msg.get_setupcodebegin() == setup_code[:2]
lp.sec("try a bad setup code")
with pytest.raises(ValueError):
msg.continue_key_transfer(str(reversed(setup_code)))
lp.sec("try a good setup code")
print("*************** Incoming ASM File at: ", msg.filename)
print("*************** Setup Code: ", setup_code)
msg.continue_key_transfer(setup_code)

View File

@@ -108,3 +108,43 @@ def test_provider_info():
def test_provider_info_none():
assert lib.dc_provider_new_from_email(cutil.as_dc_charpointer("email@unexistent.no")) == ffi.NULL
def test_get_info_closed():
ctx = ffi.gc(
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
lib.dc_context_unref,
)
info = cutil.from_dc_charpointer(lib.dc_get_info(ctx))
assert 'deltachat_core_version' in info
assert 'database_dir' not in info
def test_get_info_open(tmpdir):
ctx = ffi.gc(
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
lib.dc_context_unref,
)
db_fname = tmpdir.join("test.db")
lib.dc_open(ctx, db_fname.strpath.encode("ascii"), ffi.NULL)
info = cutil.from_dc_charpointer(lib.dc_get_info(ctx))
assert 'deltachat_core_version' in info
assert 'database_dir' in info
def test_is_open_closed():
ctx = ffi.gc(
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
lib.dc_context_unref,
)
assert lib.dc_is_open(ctx) == 0
def test_is_open_actually_open(tmpdir):
ctx = ffi.gc(
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
lib.dc_context_unref,
)
db_fname = tmpdir.join("test.db")
lib.dc_open(ctx, db_fname.strpath.encode("ascii"), ffi.NULL)
assert lib.dc_is_open(ctx) == 1

23
spec.md
View File

@@ -117,7 +117,8 @@ The sender plus the recipients are the group members.
To allow different groups with the same members,
groups are identified by a group-id.
The group-id MUST be created only from the characters
`0`-`9`, `A`-`Z`, `a`-`z` `_` and `-`.
`0`-`9`, `A`-`Z`, `a`-`z` `_` and `-`
and MUST have a length of at least 11 characters.
Groups MUST have a group-name.
The group-name is any non-zero-length UTF-8 string.
@@ -144,9 +145,9 @@ The message-id MUST have the format `Gr.<group-id>.<unique data>`.
From: member1@domain
To: member2@domain, member3@domain
Chat-Version: 1.0
Chat-Group-ID: 1234xyZ
Chat-Group-ID: 12345uvwxyZ
Chat-Group-Name: My Group
Message-ID: Gr.1234xyZ.0001@domain
Message-ID: Gr.12345uvwxyZ.0001@domain
Subject: Chat: My Group: Hello group ...
Hello group - this group contains three members
@@ -196,10 +197,10 @@ and the message SHOULD appear as a message or action from the sender.
From: member1@domain
To: member2@domain, member3@domain, member4@domain
Chat-Version: 1.0
Chat-Group-ID: 1234xyZ
Chat-Group-ID: 12345uvwxyZ
Chat-Group-Name: My Group
Chat-Group-Member-Added: member4@domain
Message-ID: Gr.1234xyZ.0002@domain
Message-ID: Gr.12345uvwxyZ.0002@domain
Subject: Chat: My Group: Hello, ...
Hello, I've added member4@domain to our group. Now we have 4 members.
@@ -209,10 +210,10 @@ To remove a member:
From: member1@domain
To: member2@domain, member3@domain
Chat-Version: 1.0
Chat-Group-ID: 1234xyZ
Chat-Group-ID: 12345uvwxyZ
Chat-Group-Name: My Group
Chat-Group-Member-Removed: member4@domain
Message-ID: Gr.1234xyZ.0003@domain
Message-ID: Gr.12345uvwxyZ.0003@domain
Subject: Chat: My Group: Hello, ...
Hello, I've removed member4@domain from our group. Now we have 3 members.
@@ -233,10 +234,10 @@ and the message SHOULD appear as a message or action from the sender.
From: member1@domain
To: member2@domain, member3@domain
Chat-Version: 1.0
Chat-Group-ID: 1234xyZ
Chat-Group-ID: 12345uvwxyZ
Chat-Group-Name: Our Group
Chat-Group-Name-Changed: My Group
Message-ID: Gr.1234xyZ.0004@domain
Message-ID: Gr.12345uvwxyZ.0004@domain
Subject: Chat: Our Group: Hello, ...
Hello, I've changed the group name from "My Group" to "Our Group".
@@ -262,10 +263,10 @@ and the message SHOULD appear as a message or action from the sender.
From: member1@domain
To: member2@domain, member3@domain
Chat-Version: 1.0
Chat-Group-ID: 1234xyZ
Chat-Group-ID: 12345uvwxyZ
Chat-Group-Name: Our Group
Chat-Group-Image: image.jpg
Message-ID: Gr.1234xyZ.0005@domain
Message-ID: Gr.12345uvwxyZ.0005@domain
Subject: Chat: Our Group: Hello, ...
Content-Type: multipart/mixed; boundary="==break=="

View File

@@ -3,7 +3,7 @@ use std::ffi::CStr;
use std::str::FromStr;
use std::{fmt, str};
use mmime::mailimf_types::*;
use mmime::mailimf::types::*;
use crate::constants::*;
use crate::contact::*;

View File

@@ -925,7 +925,9 @@ fn get_draft_msg_id(context: &Context, chat_id: u32) -> u32 {
}
pub fn get_draft(context: &Context, chat_id: u32) -> Result<Option<Message>, Error> {
ensure!(chat_id > DC_CHAT_ID_LAST_SPECIAL, "Invalid chat ID");
if chat_id <= DC_CHAT_ID_LAST_SPECIAL {
return Ok(None);
}
let draft_msg_id = get_draft_msg_id(context, chat_id);
if draft_msg_id == 0 {
return Ok(None);
@@ -1332,7 +1334,7 @@ pub fn add_to_chat_contacts_table(context: &Context, chat_id: u32, contact_id: u
pub fn add_contact_to_chat(context: &Context, chat_id: u32, contact_id: u32) -> bool {
match add_contact_to_chat_ex(context, chat_id, contact_id, false) {
Ok(res) => res,
Ok(res) => res,
Err(err) => {
error!(context, "failed to add contact: {}", err);
false
@@ -1347,7 +1349,10 @@ pub(crate) fn add_contact_to_chat_ex(
contact_id: u32,
from_handshake: bool,
) -> Result<bool, Error> {
ensure!(chat_id > DC_CHAT_ID_LAST_SPECIAL, "can not add member to special chats");
ensure!(
chat_id > DC_CHAT_ID_LAST_SPECIAL,
"can not add member to special chats"
);
let contact = Contact::get_by_id(context, contact_id)?;
let mut msg = Message::default();
@@ -1355,74 +1360,77 @@ pub(crate) fn add_contact_to_chat_ex(
/*this also makes sure, not contacts are added to special or normal chats*/
let mut chat = Chat::load_from_db(context, chat_id)?;
ensure!(real_group_exists(context, chat_id),
"chat_id {} is not a group where one can add members", chat_id);
ensure!(Contact::real_exists_by_id(context, contact_id) && contact_id != DC_CONTACT_ID_SELF,
"invalid contact_id {} for removal in group", contact_id);
ensure!(
real_group_exists(context, chat_id),
"chat_id {} is not a group where one can add members",
chat_id
);
ensure!(
Contact::real_exists_by_id(context, contact_id) && contact_id != DC_CONTACT_ID_SELF,
"invalid contact_id {} for removal in group",
contact_id
);
if !is_contact_in_chat(context, chat_id, DC_CONTACT_ID_SELF as u32) {
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
emit_event!(
if !is_contact_in_chat(context, chat_id, DC_CONTACT_ID_SELF as u32) {
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
emit_event!(
context,
Event::ErrorSelfNotInGroup("Cannot add contact to group; self not in group.".into())
);
bail!("can not add contact because our account is not part of it");
}
if from_handshake && chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 1 {
chat.param.remove(Param::Unpromoted);
chat.update_param(context).unwrap();
}
let self_addr = context
.sql
.get_config(context, "configured_addr")
.unwrap_or_default();
if contact.get_addr() == &self_addr {
bail!("invalid attempt to add self e-mail address to group");
}
// ourself is added using DC_CONTACT_ID_SELF, do not add it explicitly.
// if SELF is not in the group, members cannot be added at all.
if is_contact_in_chat(context, chat_id, contact_id) {
if !from_handshake {
return Ok(true);
}
} else {
// else continue and send status mail
if chat.typ == Chattype::VerifiedGroup {
if contact.is_verified(context) != VerifiedStatus::BidirectVerified {
error!(
context,
Event::ErrorSelfNotInGroup(
"Cannot add contact to group; self not in group.".into()
)
"Only bidirectional verified contacts can be added to verified groups."
);
bail!("can not add contact because our account is not part of it");
return Ok(false);
}
if from_handshake && chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 1
{
chat.param.remove(Param::Unpromoted);
chat.update_param(context).unwrap();
}
let self_addr = context
.sql
.get_config(context, "configured_addr")
.unwrap_or_default();
if contact.get_addr() == &self_addr {
bail!("invalid attempt to add self e-mail address to group");
}
// ourself is added using DC_CONTACT_ID_SELF, do not add it explicitly.
// if SELF is not in the group, members cannot be added at all.
if is_contact_in_chat(context, chat_id, contact_id) {
if !from_handshake {
return Ok(true);
}
} else {
// else continue and send status mail
if chat.typ == Chattype::VerifiedGroup {
if contact.is_verified(context) != VerifiedStatus::BidirectVerified {
error!(
context,
"Only bidirectional verified contacts can be added to verified groups."
);
return Ok(false);
}
}
if !add_to_chat_contacts_table(context, chat_id, contact_id) {
return Ok(false);
}
}
if chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
msg.type_0 = Viewtype::Text;
msg.text = Some(context.stock_system_msg(
StockMessage::MsgAddMember,
contact.get_addr(),
"",
DC_CONTACT_ID_SELF as u32,
));
msg.param.set_int(Param::Cmd, 4);
msg.param.set(Param::Arg, contact.get_addr());
msg.param.set_int(Param::Arg2, from_handshake.into());
msg.id = send_msg(context, chat_id, &mut msg).unwrap_or_default();
context.call_cb(Event::MsgsChanged {
chat_id,
msg_id: msg.id,
});
}
context.call_cb(Event::MsgsChanged { chat_id, msg_id: 0 });
return Ok(true);
}
if !add_to_chat_contacts_table(context, chat_id, contact_id) {
return Ok(false);
}
}
if chat.param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
msg.type_0 = Viewtype::Text;
msg.text = Some(context.stock_system_msg(
StockMessage::MsgAddMember,
contact.get_addr(),
"",
DC_CONTACT_ID_SELF as u32,
));
msg.param.set_int(Param::Cmd, 4);
msg.param.set(Param::Arg, contact.get_addr());
msg.param.set_int(Param::Arg2, from_handshake.into());
msg.id = send_msg(context, chat_id, &mut msg).unwrap_or_default();
context.call_cb(Event::MsgsChanged {
chat_id,
msg_id: msg.id,
});
}
context.call_cb(Event::MsgsChanged { chat_id, msg_id: 0 });
return Ok(true);
}
fn real_group_exists(context: &Context, chat_id: u32) -> bool {
@@ -1880,8 +1888,8 @@ mod tests {
#[test]
fn test_get_draft_special_chat_id() {
let t = dummy_context();
let draft = get_draft(&t.ctx, DC_CHAT_ID_LAST_SPECIAL);
assert!(draft.is_err());
let draft = get_draft(&t.ctx, DC_CHAT_ID_LAST_SPECIAL).unwrap();
assert!(draft.is_none());
}
#[test]

View File

@@ -65,13 +65,13 @@ pub(crate) const DC_FP_NO_AUTOCRYPT_HEADER: i32 = 2;
pub(crate) const DC_FP_ADD_AUTOCRYPT_HEADER: i32 = 1;
/// param1 is a directory where the keys are written to
const DC_IMEX_EXPORT_SELF_KEYS: usize = 1;
pub const DC_IMEX_EXPORT_SELF_KEYS: i32 = 1;
/// param1 is a directory where the keys are searched in and read from
const DC_IMEX_IMPORT_SELF_KEYS: usize = 2;
pub const DC_IMEX_IMPORT_SELF_KEYS: i32 = 2;
/// param1 is a directory where the backup is written to
const DC_IMEX_EXPORT_BACKUP: usize = 11;
pub const DC_IMEX_EXPORT_BACKUP: i32 = 11;
/// param1 is the file with the backup to import
const DC_IMEX_IMPORT_BACKUP: usize = 12;
pub const DC_IMEX_IMPORT_BACKUP: i32 = 12;
/// virtual chat showing all messages belonging to chats flagged with chats.blocked=2
pub(crate) const DC_CHAT_ID_DEADDROP: u32 = 1;

View File

@@ -66,6 +66,30 @@ pub struct RunningState {
pub shall_stop_ongoing: bool,
}
/// Return some info about deltachat-core
///
/// This contains information mostly about the library itself, the
/// actual keys and their values which will be present are not
/// guaranteed. Calling [Context::get_info] also includes information
/// about the context on top of the information here.
pub fn get_info() -> HashMap<&'static str, String> {
let mut res = HashMap::new();
res.insert("deltachat_core_version", format!("v{}", &*DC_VERSION_STR));
res.insert("sqlite_version", rusqlite::version().to_string());
res.insert(
"sqlite_thread_safe",
unsafe { rusqlite::ffi::sqlite3_threadsafe() }.to_string(),
);
res.insert(
"arch",
(::std::mem::size_of::<*mut libc::c_void>())
.wrapping_mul(8)
.to_string(),
);
res.insert("level", "awesome".into());
res
}
impl Context {
pub fn new(cb: Box<ContextCallback>, os_name: String, dbfile: PathBuf) -> Result<Context> {
let mut blob_fname = OsString::new();
@@ -209,19 +233,7 @@ impl Context {
.get_config(self, "configured_mvbox_folder")
.unwrap_or_else(|| "<unset>".to_string());
let mut res = HashMap::new();
res.insert("deltachat_core_version", format!("v{}", &*DC_VERSION_STR));
res.insert("sqlite_version", rusqlite::version().to_string());
res.insert(
"sqlite_thread_safe",
unsafe { rusqlite::ffi::sqlite3_threadsafe() }.to_string(),
);
res.insert(
"arch",
(::std::mem::size_of::<*mut libc::c_void>())
.wrapping_mul(8)
.to_string(),
);
let mut res = get_info();
res.insert("number_of_chats", chats.to_string());
res.insert("number_of_chat_messages", real_msgs.to_string());
res.insert("messages_in_contact_requests", deaddrop_msgs.to_string());
@@ -251,7 +263,6 @@ impl Context {
pub_key_cnt.unwrap_or_default().to_string(),
);
res.insert("fingerprint", fingerprint_str);
res.insert("level", "awesome".into());
res
}
@@ -504,6 +515,14 @@ mod tests {
let t = dummy_context();
let info = t.ctx.get_info();
assert!(info.get("database_dir").is_some());
}
#[test]
fn test_get_info_no_context() {
let info = get_info();
assert!(info.get("deltachat_core_version").is_some());
assert!(info.get("database_dir").is_none());
assert_eq!(info.get("level").unwrap(), "awesome");
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,12 +6,12 @@ use charset::Charset;
use deltachat_derive::{FromSql, ToSql};
use libc::{strcmp, strlen, strncmp};
use mmime::clist::*;
use mmime::mailimf::types::*;
use mmime::mailimf::*;
use mmime::mailimf_types::*;
use mmime::mailmime::content::*;
use mmime::mailmime::disposition::*;
use mmime::mailmime::types::*;
use mmime::mailmime::*;
use mmime::mailmime_content::*;
use mmime::mailmime_disposition::*;
use mmime::mailmime_types::*;
use mmime::mmapstring::*;
use mmime::other::*;
@@ -31,7 +31,7 @@ use crate::stock::StockMessage;
pub struct MimeParser<'a> {
pub context: &'a Context,
pub parts: Vec<Part>,
pub mimeroot: *mut mailmime,
pub mimeroot: *mut Mailmime,
pub header: HashMap<String, *mut mailimf_field>,
pub header_root: *mut mailimf_fields,
pub header_protected: *mut mailimf_fields,
@@ -40,7 +40,7 @@ pub struct MimeParser<'a> {
pub decrypting_failed: bool,
pub e2ee_helper: E2eeHelper,
pub is_forwarded: bool,
pub reports: Vec<*mut mailmime>,
pub reports: Vec<*mut Mailmime>,
pub is_system_message: SystemMessage,
pub location_kml: Option<location::Kml>,
pub message_kml: Option<location::Kml>,
@@ -363,7 +363,7 @@ impl<'a> MimeParser<'a> {
}
}
unsafe fn parse_mime_recursive(&mut self, mime: *mut mailmime) -> bool {
unsafe fn parse_mime_recursive(&mut self, mime: *mut Mailmime) -> bool {
if mime.is_null() {
return false;
}
@@ -428,7 +428,7 @@ impl<'a> MimeParser<'a> {
}
}
unsafe fn handle_multiple(&mut self, mime: *mut mailmime) -> bool {
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
@@ -468,7 +468,7 @@ impl<'a> MimeParser<'a> {
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);
any_part_added = self.parse_mime_recursive((*cur).data as *mut Mailmime);
}
}
(DC_MIMETYPE_MP_NOT_DECRYPTABLE, _, _) => {
@@ -538,7 +538,7 @@ impl<'a> MimeParser<'a> {
plain_cnt += 1;
}
(DC_MIMETYPE_TEXT_HTML, _, _) => {
html_part = cur_data as *mut mailmime;
html_part = cur_data as *mut Mailmime;
html_cnt += 1;
}
_ => {}
@@ -565,7 +565,7 @@ impl<'a> MimeParser<'a> {
any_part_added
}
unsafe fn add_single_part_if_known(&mut self, mime: *mut mailmime) -> bool {
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;
@@ -969,7 +969,7 @@ unsafe fn hash_header(out: &mut HashMap<String, *mut mailimf_field>, in_0: *cons
}
}
unsafe fn mailmime_get_mime_type(mime: *mut mailmime) -> (libc::c_int, Viewtype, Option<String>) {
unsafe fn mailmime_get_mime_type(mime: *mut Mailmime) -> (libc::c_int, Viewtype, Option<String>) {
let c = (*mime).mm_content_type;
let unknown_type = (0, Viewtype::Unknown, None);
@@ -1093,7 +1093,7 @@ fn reconcat_mime(typ: Option<&str>, subtype: Option<&str>) -> String {
format!("{}/{}", typ, subtype)
}
unsafe fn mailmime_is_attachment_disposition(mime: *mut mailmime) -> bool {
unsafe fn mailmime_is_attachment_disposition(mime: *mut Mailmime) -> bool {
if (*mime).mm_mime_fields.is_null() {
return false;
}
@@ -1118,7 +1118,7 @@ unsafe fn mailmime_is_attachment_disposition(mime: *mut mailmime) -> bool {
/* low-level-tools for working with mailmime structures directly */
pub unsafe fn mailmime_find_ct_parameter(
mime: *mut mailmime,
mime: *mut Mailmime,
name: &str,
) -> *mut mailmime_parameter {
if mime.is_null()
@@ -1140,7 +1140,7 @@ pub unsafe fn mailmime_find_ct_parameter(
ptr::null_mut()
}
pub unsafe fn mailmime_transfer_decode(mime: *mut mailmime) -> Result<Vec<u8>, Error> {
pub unsafe fn mailmime_transfer_decode(mime: *mut Mailmime) -> Result<Vec<u8>, Error> {
ensure!(!mime.is_null(), "invalid inputs");
let mut mime_transfer_encoding = MAILMIME_MECHANISM_BINARY as libc::c_int;
@@ -1295,7 +1295,7 @@ pub unsafe fn mailimf_find_field(
}
/*the result is a pointer to mime, must not be freed*/
pub unsafe fn mailmime_find_mailimf_fields(mime: *mut mailmime) -> *mut mailimf_fields {
pub unsafe fn mailmime_find_mailimf_fields(mime: *mut Mailmime) -> *mut mailimf_fields {
if mime.is_null() {
return ptr::null_mut();
}
@@ -1353,7 +1353,7 @@ mod tests {
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 mime: *mut Mailmime = ptr::null_mut();
let mut dummy = 0;
let res = mailmime_parse(txt, strlen(txt), &mut dummy, &mut mime);

View File

@@ -4,11 +4,11 @@ use std::ptr;
use itertools::join;
use libc::{free, strcmp, strlen};
use mmime::clist::*;
use mmime::mailimf::types::*;
use mmime::mailimf::*;
use mmime::mailimf_types::*;
use mmime::mailmime::content::*;
use mmime::mailmime::types::*;
use mmime::mailmime::*;
use mmime::mailmime_content::*;
use mmime::mailmime_types::*;
use mmime::other::*;
use sha2::{Digest, Sha256};
@@ -39,8 +39,7 @@ enum CreateEvent {
/// Receive a message and add it to the database.
pub unsafe fn dc_receive_imf(
context: &Context,
imf_raw_not_terminated: *const libc::c_char,
imf_raw_bytes: libc::size_t,
imf_raw: &[u8],
server_folder: impl AsRef<str>,
server_uid: u32,
flags: u32,
@@ -61,9 +60,8 @@ 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 body = std::slice::from_raw_parts(imf_raw_not_terminated as *const u8, imf_raw_bytes);
let mut mime_parser = MimeParser::new(context);
mime_parser.parse(body);
mime_parser.parse(imf_raw);
if mime_parser.header.is_empty() {
// Error - even adding an empty record won't help as we do not know the message ID
@@ -204,8 +202,7 @@ pub unsafe fn dc_receive_imf(
if let Err(err) = add_parts(
context,
&mut mime_parser,
imf_raw_not_terminated,
imf_raw_bytes,
imf_raw,
incoming,
&mut incoming_origin,
server_folder.as_ref(),
@@ -292,8 +289,7 @@ pub unsafe fn dc_receive_imf(
unsafe fn add_parts(
context: &Context,
mut mime_parser: &mut MimeParser,
imf_raw_not_terminated: *const libc::c_char,
imf_raw_bytes: libc::size_t,
imf_raw: &[u8],
incoming: i32,
incoming_origin: &mut Origin,
server_folder: impl AsRef<str>,
@@ -683,10 +679,7 @@ unsafe fn add_parts(
part.bytes,
*hidden,
if save_mime_headers {
Some(String::from_utf8_lossy(std::slice::from_raw_parts(
imf_raw_not_terminated as *const u8,
imf_raw_bytes,
)))
Some(String::from_utf8_lossy(imf_raw))
} else {
None
},
@@ -788,7 +781,7 @@ unsafe fn handle_reports(
.data
} else {
ptr::null_mut()
}) as *mut mailmime;
}) as *mut Mailmime;
if !report_data.is_null()
&& (*(*(*report_data).mm_content_type).ct_type).tp_type

View File

@@ -1,11 +1,11 @@
use itertools::Itertools;
use std::borrow::Cow;
use std::ffi::CString;
use std::ptr;
use charset::Charset;
use libc::{free, strlen};
use mmime::mailmime_decode::*;
use mmime::mmapstring::*;
use mmime::mailmime::decode::mailmime_encoded_phrase_parse;
use mmime::other::*;
use percent_encoding::{percent_decode, utf8_percent_encode, AsciiSet, CONTROLS};
@@ -25,195 +25,49 @@ use crate::dc_tools::*;
* @return Returns the encoded string which must be free()'d when no longed needed.
* On errors, NULL is returned.
*/
pub unsafe fn dc_encode_header_words(to_encode_r: impl AsRef<str>) -> String {
let to_encode =
CString::new(to_encode_r.as_ref().as_bytes()).expect("invalid cstring to_encode");
let mut ok_to_continue = true;
let mut ret_str: *mut libc::c_char = ptr::null_mut();
let mut cur: *const libc::c_char = to_encode.as_ptr();
let mmapstr: *mut MMAPString = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
if mmapstr.is_null() {
ok_to_continue = false;
}
loop {
if !ok_to_continue {
if !mmapstr.is_null() {
mmap_string_free(mmapstr);
}
break;
} else {
if *cur as libc::c_int != '\u{0}' as i32 {
let begin: *const libc::c_char;
let mut end: *const libc::c_char;
let mut do_quote: bool;
let mut quote_words: libc::c_int;
begin = cur;
end = begin;
quote_words = 0i32;
do_quote = true;
while *cur as libc::c_int != '\u{0}' as i32 {
get_word(cur, &mut cur, &mut do_quote);
if !do_quote {
break;
}
quote_words = 1i32;
end = cur;
if *cur as libc::c_int != '\u{0}' as i32 {
cur = cur.offset(1isize)
}
}
if 0 != quote_words {
if !quote_word(
mmapstr,
begin,
end.wrapping_offset_from(begin) as libc::size_t,
) {
ok_to_continue = false;
continue;
}
if *end as libc::c_int == ' ' as i32 || *end as libc::c_int == '\t' as i32 {
if mmap_string_append_c(mmapstr, *end).is_null() {
ok_to_continue = false;
continue;
}
end = end.offset(1isize)
}
if *end as libc::c_int != '\u{0}' as i32 {
if mmap_string_append_len(
mmapstr,
end,
cur.wrapping_offset_from(end) as libc::size_t,
)
.is_null()
{
ok_to_continue = false;
continue;
}
}
} else if mmap_string_append_len(
mmapstr,
begin,
cur.wrapping_offset_from(begin) as libc::size_t,
)
.is_null()
{
ok_to_continue = false;
continue;
}
if !(*cur as libc::c_int == ' ' as i32 || *cur as libc::c_int == '\t' as i32) {
continue;
}
if mmap_string_append_c(mmapstr, *cur).is_null() {
ok_to_continue = false;
continue;
}
cur = cur.offset(1isize);
} else {
ret_str = strdup((*mmapstr).str_0);
ok_to_continue = false;
}
}
pub fn dc_encode_header_words(input: impl AsRef<str>) -> String {
let mut result = String::default();
for (_, group) in &input.as_ref().chars().group_by(|c| c.is_whitespace()) {
let word: String = group.collect();
result.push_str(&quote_word(&word.as_bytes()));
}
let s = to_string(ret_str);
free(ret_str.cast());
s
result
}
unsafe fn quote_word(
mmapstr: *mut MMAPString,
word: *const libc::c_char,
size: libc::size_t,
) -> bool {
let mut cur: *const libc::c_char;
let mut i = 0;
let mut hex: [libc::c_char; 4] = [0; 4];
// let mut col: libc::c_int = 0i32;
if mmap_string_append(mmapstr, b"=?utf-8?Q?\x00".as_ptr().cast()).is_null() {
return false;
}
fn must_encode(byte: u8) -> bool {
static SPECIALS: &[u8] = b",:!\"#$@[\\]^`{|}~=?_";
// col = (*mmapstr).len as libc::c_int;
cur = word;
while i < size {
let mut do_quote_char = false;
match *cur as u8 as char {
',' | ':' | '!' | '"' | '#' | '$' | '@' | '[' | '\\' | ']' | '^' | '`' | '{' | '|'
| '}' | '~' | '=' | '?' | '_' => do_quote_char = true,
_ => {
if *cur as u8 >= 128 {
do_quote_char = true;
}
}
}
if do_quote_char {
print_hex(hex.as_mut_ptr(), cur);
if mmap_string_append(mmapstr, hex.as_mut_ptr()).is_null() {
return false;
}
// col += 3i32
} else {
if *cur as libc::c_int == ' ' as i32 {
if mmap_string_append_c(mmapstr, '_' as i32 as libc::c_char).is_null() {
return false;
}
} else if mmap_string_append_c(mmapstr, *cur).is_null() {
return false;
}
// col += 3i32
}
cur = cur.offset(1isize);
i = i.wrapping_add(1)
}
if mmap_string_append(mmapstr, b"?=\x00" as *const u8 as *const libc::c_char).is_null() {
return false;
}
true
SPECIALS.into_iter().any(|b| *b == byte)
}
unsafe fn get_word(
begin: *const libc::c_char,
pend: *mut *const libc::c_char,
pto_be_quoted: *mut bool,
) {
let mut cur: *const libc::c_char = begin;
while *cur as libc::c_int != ' ' as i32
&& *cur as libc::c_int != '\t' as i32
&& *cur as libc::c_int != '\u{0}' as i32
{
cur = cur.offset(1isize)
fn quote_word(word: &[u8]) -> String {
let mut result = String::default();
let mut encoded = false;
for byte in word {
let byte = *byte;
if byte >= 128 || must_encode(byte) {
result.push_str(&format!("={:2X}", byte));
encoded = true;
} else if byte == b' ' {
result.push('_');
encoded = true;
} else {
result.push(byte as _);
}
}
*pto_be_quoted = to_be_quoted(begin, cur.wrapping_offset_from(begin) as libc::size_t);
*pend = cur;
if encoded {
result = format!("=?utf-8?Q?{}?=", &result);
}
result
}
/* ******************************************************************************
* Encode/decode header words, RFC 2047
******************************************************************************/
/* see comment below */
unsafe fn to_be_quoted(word: *const libc::c_char, size: libc::size_t) -> bool {
let mut cur: *const libc::c_char = word;
let mut i = 0;
while i < size {
match *cur as libc::c_int {
44 | 58 | 33 | 34 | 35 | 36 | 64 | 91 | 92 | 93 | 94 | 96 | 123 | 124 | 125 | 126
| 61 | 63 | 95 => return true,
_ => {
if *cur as libc::c_uchar as libc::c_int >= 128i32 {
return true;
}
}
}
cur = cur.offset(1isize);
i = i.wrapping_add(1)
}
false
}
pub unsafe fn dc_decode_header_words(in_0: *const libc::c_char) -> *mut libc::c_char {
if in_0.is_null() {
return ptr::null_mut();
@@ -319,15 +173,6 @@ pub fn dc_decode_ext_header(to_decode: &[u8]) -> Cow<str> {
String::from_utf8_lossy(to_decode)
}
unsafe fn print_hex(target: *mut libc::c_char, cur: *const libc::c_char) {
assert!(!target.is_null());
assert!(!cur.is_null());
let bytes = std::slice::from_raw_parts(cur as *const _, strlen(cur));
let raw = CString::yolo(format!("={}", &hex::encode_upper(bytes)[..2]));
libc::memcpy(target as *mut _, raw.as_ptr() as *const _, 4);
}
#[cfg(test)]
mod tests {
use super::*;
@@ -429,18 +274,6 @@ mod tests {
assert_eq!(dc_needs_ext_header("a b"), true);
}
#[test]
fn test_print_hex() {
let mut hex: [libc::c_char; 4] = [0; 4];
let cur = b"helloworld" as *const u8 as *const libc::c_char;
unsafe { print_hex(hex.as_mut_ptr(), cur) };
assert_eq!(to_string(hex.as_ptr() as *const _), "=68");
let cur = b":" as *const u8 as *const libc::c_char;
unsafe { print_hex(hex.as_mut_ptr(), cur) };
assert_eq!(to_string(hex.as_ptr() as *const _), "=3A");
}
use proptest::prelude::*;
proptest! {
@@ -456,5 +289,13 @@ mod tests {
// 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_safe(&encoded);
assert_eq!(input, decoded);
}
}
}

View File

@@ -9,9 +9,9 @@ use std::time::SystemTime;
use std::{fmt, fs, ptr};
use chrono::{Local, TimeZone};
use libc::{memcpy, strcpy, strlen, uintptr_t};
use libc::{memcpy, strlen};
use mmime::clist::*;
use mmime::mailimf_types::*;
use mmime::mailimf::types::*;
use rand::{thread_rng, Rng};
use crate::context::Context;
@@ -149,66 +149,6 @@ pub(crate) fn dc_truncate(buf: &str, approx_chars: usize, do_unwrap: bool) -> Co
}
}
#[allow(non_snake_case)]
pub(crate) unsafe fn dc_truncate_n_unwrap_str(
buf: *mut libc::c_char,
approx_characters: libc::c_int,
do_unwrap: libc::c_int,
) {
/* Function unwraps the given string and removes unnecessary whitespace.
Function stops processing after approx_characters are processed.
(as we're using UTF-8, for simplicity, we cut the string only at whitespaces). */
/* a single line is truncated `...` instead of `[...]` (the former is typically also used by the UI to fit strings in a rectangle) */
let ellipse_utf8: *const libc::c_char = if 0 != do_unwrap {
b" ...\x00" as *const u8 as *const libc::c_char
} else {
b" [...]\x00" as *const u8 as *const libc::c_char
};
let mut lastIsCharacter: libc::c_int = 0;
/* force unsigned - otherwise the `> ' '` comparison will fail */
let mut p1: *mut libc::c_uchar = buf as *mut libc::c_uchar;
while 0 != *p1 {
if *p1 as libc::c_int > ' ' as i32 {
lastIsCharacter = 1
} else if 0 != lastIsCharacter {
let used_bytes = (p1 as uintptr_t).wrapping_sub(buf as uintptr_t) as libc::size_t;
if dc_utf8_strnlen(buf, used_bytes) >= approx_characters as usize {
let buf_bytes = strlen(buf);
if buf_bytes.wrapping_sub(used_bytes) >= strlen(ellipse_utf8) {
strcpy(p1 as *mut libc::c_char, ellipse_utf8);
}
break;
} else {
lastIsCharacter = 0;
if 0 != do_unwrap {
*p1 = ' ' as i32 as libc::c_uchar
}
}
} else if 0 != do_unwrap {
*p1 = '\r' as i32 as libc::c_uchar
}
p1 = p1.offset(1isize)
}
if 0 != do_unwrap {
dc_remove_cr_chars(buf);
};
}
unsafe fn dc_utf8_strnlen(s: *const libc::c_char, n: libc::size_t) -> libc::size_t {
if s.is_null() {
return 0;
}
let mut j: libc::size_t = 0;
for i in 0..n {
if *s.add(i) as libc::c_int & 0xc0 != 0x80 {
j = j.wrapping_add(1)
}
}
j
}
pub(crate) unsafe fn dc_str_from_clist(
list: *const clist,
delimiter: *const libc::c_char,
@@ -530,10 +470,13 @@ pub(crate) fn dc_get_filebytes(context: &Context, path: impl AsRef<std::path::Pa
pub(crate) fn dc_delete_file(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
let path_abs = dc_get_abs_path(context, &path);
if !path_abs.exists() {
return false;
}
if !path_abs.is_file() {
warn!(
context,
"Will not delete directory \"{}\".",
"refusing to delete non-file \"{}\".",
path.as_ref().display()
);
return false;
@@ -1499,6 +1442,7 @@ mod tests {
let t = dummy_context();
let context = &t.ctx;
assert!(!dc_delete_file(context, "$BLOBDIR/lkqwjelqkwlje"));
if dc_file_exist(context, "$BLOBDIR/foobar")
|| dc_file_exist(context, "$BLOBDIR/dada")
|| dc_file_exist(context, "$BLOBDIR/foobar.dadada")
@@ -1521,6 +1465,7 @@ mod tests {
.to_string();
assert!(dc_is_blobdir_path(context, &abs_path));
assert!(dc_is_blobdir_path(context, "$BLOBDIR/fofo",));
assert!(!dc_is_blobdir_path(context, "/BLOBDIR/fofo",));
assert!(dc_file_exist(context, &abs_path));

View File

@@ -8,14 +8,14 @@ use std::str::FromStr;
use libc::{free, strcmp, strlen, strncmp};
use mmime::clist::*;
use mmime::mailimf::types::*;
use mmime::mailimf::types_helper::*;
use mmime::mailimf::*;
use mmime::mailimf_types::*;
use mmime::mailimf_types_helper::*;
use mmime::mailmime::content::*;
use mmime::mailmime::types::*;
use mmime::mailmime::types_helper::*;
use mmime::mailmime::write_mem::*;
use mmime::mailmime::*;
use mmime::mailmime_content::*;
use mmime::mailmime_types::*;
use mmime::mailmime_types_helper::*;
use mmime::mailmime_write_mem::*;
use mmime::mailprivacy_prepare_mime;
use mmime::mmapstring::*;
use mmime::{mailmime_substitute, MAILIMF_NO_ERROR, MAIL_NO_ERROR};
@@ -81,7 +81,7 @@ impl EncryptHelper {
e2ee_guaranteed: bool,
min_verified: libc::c_int,
do_gossip: bool,
mut in_out_message: *mut mailmime,
mut in_out_message: *mut Mailmime,
imffields_unprotected: *mut mailimf_fields,
) -> Result<bool> {
/* libEtPan's pgp_encrypt_mime() takes the parent as the new root.
@@ -146,12 +146,12 @@ impl EncryptHelper {
/* encrypt message */
unsafe {
mailprivacy_prepare_mime(in_out_message);
let mut part_to_encrypt: *mut mailmime =
let mut part_to_encrypt: *mut Mailmime =
(*in_out_message).mm_data.mm_message.mm_msg_mime;
(*part_to_encrypt).mm_parent = ptr::null_mut();
let imffields_encrypted: *mut mailimf_fields = 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: *mut mailmime = mailmime_new(
let message_to_encrypt: *mut Mailmime = mailmime_new(
MAILMIME_MESSAGE as libc::c_int,
ptr::null(),
0 as libc::size_t,
@@ -182,7 +182,8 @@ impl EncryptHelper {
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-")
if fld_name.starts_with("Secure-Join")
|| (fld_name.starts_with("Chat-") && fld_name != "Chat-Version")
{
move_to_encrypted = true;
}
@@ -248,7 +249,7 @@ impl EncryptHelper {
if let Ok(ctext_v) = ctext {
/* create MIME-structure that will contain the encrypted text */
let mut encrypted_part: *mut mailmime = new_data_part(
let mut encrypted_part: *mut Mailmime = new_data_part(
ptr::null_mut(),
0 as libc::size_t,
"multipart/encrypted",
@@ -256,7 +257,7 @@ impl EncryptHelper {
)?;
let content: *mut mailmime_content = (*encrypted_part).mm_content_type;
wrapmime::append_ct_param(content, "protocol", "application/pgp-encrypted")?;
let version_mime: *mut mailmime = new_data_part(
let version_mime: *mut Mailmime = new_data_part(
VERSION_CONTENT.as_mut_ptr() as *mut libc::c_void,
strlen(VERSION_CONTENT.as_mut_ptr()),
"application/pgp-encrypted",
@@ -266,7 +267,7 @@ impl EncryptHelper {
// we assume that ctext_v is not dropped until the end
// of this if-scope
let ctext_part: *mut mailmime = new_data_part(
let ctext_part: *mut Mailmime = new_data_part(
ctext_v.as_ptr() as *mut libc::c_void,
ctext_v.len(),
"application/octet-stream",
@@ -304,7 +305,7 @@ impl E2eeHelper {
}
}
pub unsafe fn decrypt(&mut self, context: &Context, in_out_message: *mut mailmime) {
pub unsafe fn decrypt(&mut self, context: &Context, in_out_message: *mut Mailmime) {
/* return values: 0=nothing to decrypt/cannot decrypt, 1=sth. decrypted
(to detect parts that could not be decrypted, simply look for left "multipart/encrypted" MIME types */
/*just a pointer into mailmime structure, must not be freed*/
@@ -426,7 +427,7 @@ fn new_data_part(
data_bytes: libc::size_t,
content_type: &str,
default_encoding: u32,
) -> Result<*mut mailmime> {
) -> Result<*mut Mailmime> {
let content = new_content_type(&content_type)?;
unsafe {
let mut encoding: *mut mailmime_mechanism = ptr::null_mut();
@@ -565,7 +566,7 @@ unsafe fn update_gossip_peerstates(
unsafe fn decrypt_recursive(
context: &Context,
mime: *mut mailmime,
mime: *mut Mailmime,
private_keyring: &Keyring,
public_keyring_for_validate: &Keyring,
ret_valid_signatures: &mut HashSet<String>,
@@ -585,15 +586,19 @@ unsafe fn decrypt_recursive(
) == 0i32
{
for cur_data in (*(*mime).mm_data.mm_multipart.mm_mp_list).into_iter() {
let mut decrypted_mime: *mut mailmime = ptr::null_mut();
if decrypt_part(
let mut decrypted_mime: *mut Mailmime = ptr::null_mut();
let decrypted = match decrypt_part(
context,
cur_data as *mut mailmime,
cur_data as *mut Mailmime,
private_keyring,
public_keyring_for_validate,
ret_valid_signatures,
&mut decrypted_mime,
) {
Ok(res) => res,
Err(err) => bail!("decrypt_part: {}", err),
};
if decrypted {
if (*ret_gossip_headers).is_null() && ret_valid_signatures.len() > 0 {
let mut dummy: libc::size_t = 0;
let mut test: *mut mailimf_fields = ptr::null_mut();
@@ -618,7 +623,7 @@ unsafe fn decrypt_recursive(
for cur_data in (*(*mime).mm_data.mm_multipart.mm_mp_list).into_iter() {
if decrypt_recursive(
context,
cur_data as *mut mailmime,
cur_data as *mut Mailmime,
private_keyring,
public_keyring_for_validate,
ret_valid_signatures,
@@ -654,118 +659,125 @@ unsafe fn decrypt_recursive(
unsafe fn decrypt_part(
_context: &Context,
mime: *mut mailmime,
mime: *mut Mailmime,
private_keyring: &Keyring,
public_keyring_for_validate: &Keyring,
ret_valid_signatures: &mut HashSet<String>,
ret_decrypted_mime: *mut *mut mailmime,
) -> bool {
let mut ok_to_continue = true;
ret_decrypted_mime: *mut *mut Mailmime,
) -> Result<bool> {
let mime_data: *mut mailmime_data;
let mut mime_transfer_encoding: libc::c_int = MAILMIME_MECHANISM_BINARY as libc::c_int;
/* mmap_string_unref()'d if set */
let mut transfer_decoding_buffer: *mut libc::c_char = ptr::null_mut();
/* must not be free()'d */
let mut decoded_data: *const libc::c_char = ptr::null_mut();
let mut decoded_data_bytes: libc::size_t = 0;
let mut sth_decrypted = false;
let cleanup = |transfer_decoding_buffer: *mut libc::c_char| {
if !transfer_decoding_buffer.is_null() {
mmap_string_unref(transfer_decoding_buffer);
}
};
*ret_decrypted_mime = ptr::null_mut();
mime_data = (*mime).mm_data.mm_single;
/* MAILMIME_DATA_FILE indicates, the data is in a file; AFAIK this is not used on parsing */
if !((*mime_data).dt_type != MAILMIME_DATA_TEXT as libc::c_int
if (*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)
|| (*mime_data).dt_data.dt_text.dt_length <= 0
{
if !(*mime).mm_mime_fields.is_null() {
for cur_data in (*(*(*mime).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()
{
mime_transfer_encoding = (*(*field).fld_data.fld_encoding).enc_type
}
return Ok(false);
}
if !(*mime).mm_mime_fields.is_null() {
for cur_data in (*(*(*mime).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()
{
mime_transfer_encoding = (*(*field).fld_data.fld_encoding).enc_type
}
}
/* regard `Content-Transfer-Encoding:` */
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
}
/* regarding `Content-Transfer-Encoding:` */
/* mmap_string_unref()'d if set */
let mut transfer_decoding_buffer: *mut libc::c_char = ptr::null_mut();
let decoded_data: *const libc::c_char;
let mut decoded_data_bytes: libc::size_t = 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
{
decoded_data = (*mime_data).dt_data.dt_text.dt_data;
decoded_data_bytes = (*mime_data).dt_data.dt_text.dt_length;
if decoded_data.is_null() || decoded_data_bytes <= 0 {
/* no error - but no data */
return Ok(false);
}
} else {
let r: libc::c_int;
let mut current_index: libc::size_t = 0;
r = 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
{
decoded_data = (*mime_data).dt_data.dt_text.dt_data;
decoded_data_bytes = (*mime_data).dt_data.dt_text.dt_length;
if decoded_data.is_null() || decoded_data_bytes <= 0 {
/* no error - but no data */
ok_to_continue = false;
cleanup(transfer_decoding_buffer);
bail!("mailmime_part_parse returned error or invalid data");
}
decoded_data = transfer_decoding_buffer;
}
/* encrypted, decoded data in decoded_data now ... */
if has_decrypted_pgp_armor(decoded_data, decoded_data_bytes as libc::c_int) {
let add_signatures = if ret_valid_signatures.is_empty() {
Some(ret_valid_signatures)
} else {
None
};
/*if we already have fingerprints, do not add more; this ensures, only the fingerprints from the outer-most part are collected */
let plain = match dc_pgp_pk_decrypt(
std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes),
&private_keyring,
&public_keyring_for_validate,
add_signatures,
) {
Ok(plain) => plain,
Err(err) => {
cleanup(transfer_decoding_buffer);
bail!("could not decrypt: {}", err)
}
};
let plain_bytes = plain.len();
let plain_buf = plain.as_ptr() as *const libc::c_char;
let mut index: libc::size_t = 0;
let mut decrypted_mime: *mut Mailmime = ptr::null_mut();
if 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() {
mailmime_free(decrypted_mime);
}
} else {
let r: libc::c_int;
let mut current_index: libc::size_t = 0;
r = 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
{
ok_to_continue = false;
} else {
decoded_data = transfer_decoding_buffer;
}
}
if ok_to_continue {
/* encrypted, decoded data in decoded_data now ... */
if has_decrypted_pgp_armor(decoded_data, decoded_data_bytes as libc::c_int) {
let add_signatures = if ret_valid_signatures.is_empty() {
Some(ret_valid_signatures)
} else {
None
};
/*if we already have fingerprints, do not add more; this ensures, only the fingerprints from the outer-most part are collected */
if let Ok(plain) = dc_pgp_pk_decrypt(
std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes),
&private_keyring,
&public_keyring_for_validate,
add_signatures,
) {
let plain_bytes = plain.len();
let plain_buf = plain.as_ptr() as *const libc::c_char;
let mut index: libc::size_t = 0;
let mut decrypted_mime: *mut mailmime = ptr::null_mut();
if 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() {
mailmime_free(decrypted_mime);
}
} else {
*ret_decrypted_mime = decrypted_mime;
sth_decrypted = true;
}
std::mem::forget(plain);
}
}
*ret_decrypted_mime = decrypted_mime;
sth_decrypted = true;
}
std::mem::forget(plain);
}
//mailmime_substitute(mime, new_mime);
//s. mailprivacy_gnupg.c::pgp_decrypt()
if !transfer_decoding_buffer.is_null() {
mmap_string_unref(transfer_decoding_buffer);
}
cleanup(transfer_decoding_buffer);
sth_decrypted
Ok(sth_decrypted)
}
unsafe fn has_decrypted_pgp_armor(str__: *const libc::c_char, mut str_bytes: libc::c_int) -> bool {
@@ -794,7 +806,7 @@ unsafe fn has_decrypted_pgp_armor(str__: *const libc::c_char, mut str_bytes: lib
/// 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.
unsafe fn contains_report(mime: *mut mailmime) -> bool {
unsafe fn contains_report(mime: *mut Mailmime) -> bool {
if (*mime).mm_type == MAILMIME_MULTIPLE as libc::c_int {
if (*(*(*mime).mm_content_type).ct_type).tp_type
== MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int
@@ -811,7 +823,7 @@ unsafe fn contains_report(mime: *mut mailmime) -> bool {
return true;
}
for cur_data in (*(*(*mime).mm_mime_fields).fld_list).into_iter() {
if contains_report(cur_data as *mut mailmime) {
if contains_report(cur_data as *mut Mailmime) {
return true;
}
}

View File

@@ -110,6 +110,8 @@ impl Client {
) -> imap::error::Result<Self> {
let stream = net::TcpStream::connect(addr)?;
let tls = native_tls::TlsConnector::builder()
// see also: https://github.com/deltachat/deltachat-core-rust/issues/203
.danger_accept_invalid_certs(true)
.danger_accept_invalid_hostnames(true)
.build()
.unwrap();
@@ -953,14 +955,7 @@ impl Imap {
if !is_deleted && msg.body().is_some() {
let body = msg.body().unwrap();
unsafe {
dc_receive_imf(
context,
body.as_ptr() as *const libc::c_char,
body.len(),
folder.as_ref(),
server_uid,
flags as u32,
);
dc_receive_imf(context, &body, folder.as_ref(), server_uid, flags as u32);
}
}
}

View File

@@ -14,7 +14,7 @@ use crate::imap::*;
use crate::location;
use crate::login_param::LoginParam;
use crate::message::{self, Message, MessageState};
use crate::mimefactory::*;
use crate::mimefactory::{vec_contains_lowercase, Loaded, MimeFactory};
use crate::param::*;
use crate::sql;
@@ -206,57 +206,49 @@ impl Job {
#[allow(non_snake_case)]
fn do_DC_JOB_MOVE_MSG(&mut self, context: &Context) {
let ok_to_continue;
let mut dest_uid = 0;
let inbox = context.inbox.read().unwrap();
if !inbox.is_connected() {
connect_to_inbox(context, &inbox);
if !inbox.is_connected() {
self.try_again_later(3, None);
ok_to_continue = false;
} else {
ok_to_continue = true;
return;
}
} else {
ok_to_continue = true;
}
if ok_to_continue {
if let Ok(msg) = Message::load_from_db(context, self.foreign_id) {
if context
.sql
.get_config_int(context, "folders_configured")
.unwrap_or_default()
< 3
{
inbox.configure_folders(context, 0x1i32);
}
let dest_folder = context.sql.get_config(context, "configured_mvbox_folder");
if let Ok(msg) = Message::load_from_db(context, self.foreign_id) {
if context
.sql
.get_config_int(context, "folders_configured")
.unwrap_or_default()
< 3
{
inbox.configure_folders(context, 0x1i32);
}
let dest_folder = context.sql.get_config(context, "configured_mvbox_folder");
if let Some(dest_folder) = dest_folder {
let server_folder = msg.server_folder.as_ref().unwrap();
if let Some(dest_folder) = dest_folder {
let server_folder = msg.server_folder.as_ref().unwrap();
let mut dest_uid = 0;
match inbox.mv(
context,
server_folder,
msg.server_uid,
&dest_folder,
&mut dest_uid,
) {
ImapResult::RetryLater => {
self.try_again_later(3i32, None);
}
ImapResult::Success => {
message::update_server_uid(
context,
&msg.rfc724_mid,
&dest_folder,
dest_uid,
);
}
ImapResult::Failed | ImapResult::AlreadyDone => {}
match inbox.mv(
context,
server_folder,
msg.server_uid,
&dest_folder,
&mut dest_uid,
) {
ImapResult::RetryLater => {
self.try_again_later(3i32, None);
}
ImapResult::Success => {
message::update_server_uid(
context,
&msg.rfc724_mid,
&dest_folder,
dest_uid,
);
}
ImapResult::Failed | ImapResult::AlreadyDone => {}
}
}
}
@@ -264,99 +256,75 @@ impl Job {
#[allow(non_snake_case)]
fn do_DC_JOB_DELETE_MSG_ON_IMAP(&mut self, context: &Context) {
let mut delete_from_server = 1;
let inbox = context.inbox.read().unwrap();
if let Ok(mut msg) = Message::load_from_db(context, self.foreign_id) {
if !msg.rfc724_mid.is_empty() {
let ok_to_continue1;
/* eg. device messages have no Message-ID */
let mut delete_from_server = true;
if message::rfc724_mid_cnt(context, &msg.rfc724_mid) != 1 {
info!(
context,
"The message is deleted from the server when all parts are deleted.",
);
delete_from_server = 0i32
delete_from_server = false;
}
/* if this is the last existing part of the message, we delete the message from the server */
if 0 != delete_from_server {
let ok_to_continue;
if delete_from_server {
if !inbox.is_connected() {
connect_to_inbox(context, &inbox);
if !inbox.is_connected() {
self.try_again_later(3i32, None);
ok_to_continue = false;
} else {
ok_to_continue = true;
return;
}
} else {
ok_to_continue = true;
}
if ok_to_continue {
let mid = msg.rfc724_mid;
let server_folder = msg.server_folder.as_ref().unwrap();
if 0 == inbox.delete_msg(context, &mid, server_folder, &mut msg.server_uid)
{
self.try_again_later(-1i32, None);
ok_to_continue1 = false;
} else {
ok_to_continue1 = true;
}
} else {
ok_to_continue1 = false;
let mid = msg.rfc724_mid;
let server_folder = msg.server_folder.as_ref().unwrap();
if 0 == inbox.delete_msg(context, &mid, server_folder, &mut msg.server_uid) {
self.try_again_later(-1i32, None);
return;
}
} else {
ok_to_continue1 = true;
}
if ok_to_continue1 {
Message::delete_from_db(context, msg.id);
}
Message::delete_from_db(context, msg.id);
}
}
}
#[allow(non_snake_case)]
fn do_DC_JOB_MARKSEEN_MSG_ON_IMAP(&mut self, context: &Context) {
let ok_to_continue;
let inbox = context.inbox.read().unwrap();
if !inbox.is_connected() {
connect_to_inbox(context, &inbox);
if !inbox.is_connected() {
self.try_again_later(3i32, None);
ok_to_continue = false;
} else {
ok_to_continue = true;
return;
}
} else {
ok_to_continue = true;
}
if ok_to_continue {
if let Ok(msg) = Message::load_from_db(context, self.foreign_id) {
let server_folder = msg.server_folder.as_ref().unwrap();
match inbox.set_seen(context, server_folder, msg.server_uid) {
ImapResult::Failed => {}
ImapResult::RetryLater => {
self.try_again_later(3i32, None);
}
_ => {
if 0 != msg.param.get_int(Param::WantsMdn).unwrap_or_default()
&& 0 != context
.sql
.get_config_int(context, "mdns_enabled")
.unwrap_or_else(|| 1)
{
let folder = msg.server_folder.as_ref().unwrap();
if let Ok(msg) = Message::load_from_db(context, self.foreign_id) {
let server_folder = msg.server_folder.as_ref().unwrap();
match inbox.set_seen(context, server_folder, msg.server_uid) {
ImapResult::Failed => {}
ImapResult::RetryLater => {
self.try_again_later(3i32, None);
}
_ => {
if 0 != msg.param.get_int(Param::WantsMdn).unwrap_or_default()
&& 0 != context
.sql
.get_config_int(context, "mdns_enabled")
.unwrap_or_else(|| 1)
{
let folder = msg.server_folder.as_ref().unwrap();
match inbox.set_mdnsent(context, folder, msg.server_uid) {
ImapResult::RetryLater => {
self.try_again_later(3i32, None);
}
ImapResult::Success => {
send_mdn(context, msg.id);
}
ImapResult::Failed | ImapResult::AlreadyDone => {}
match inbox.set_mdnsent(context, folder, msg.server_uid) {
ImapResult::RetryLater => {
self.try_again_later(3i32, None);
}
ImapResult::Success => {
send_mdn(context, msg.id);
}
ImapResult::Failed | ImapResult::AlreadyDone => {}
}
}
}
@@ -366,47 +334,40 @@ impl Job {
#[allow(non_snake_case)]
fn do_DC_JOB_MARKSEEN_MDN_ON_IMAP(&mut self, context: &Context) {
let ok_to_continue;
let folder = self
.param
.get(Param::ServerFolder)
.unwrap_or_default()
.to_string();
let uid = self.param.get_int(Param::ServerUid).unwrap_or_default() as u32;
let mut dest_uid = 0;
let inbox = context.inbox.read().unwrap();
if !inbox.is_connected() {
connect_to_inbox(context, &inbox);
if !inbox.is_connected() {
self.try_again_later(3, None);
ok_to_continue = false;
} else {
ok_to_continue = true;
return;
}
} else {
ok_to_continue = true;
}
if ok_to_continue {
if inbox.set_seen(context, &folder, uid) == ImapResult::Failed {
self.try_again_later(3i32, None);
if inbox.set_seen(context, &folder, uid) == ImapResult::Failed {
self.try_again_later(3i32, None);
}
if 0 != self.param.get_int(Param::AlsoMove).unwrap_or_default() {
if context
.sql
.get_config_int(context, "folders_configured")
.unwrap_or_default()
< 3
{
inbox.configure_folders(context, 0x1i32);
}
if 0 != self.param.get_int(Param::AlsoMove).unwrap_or_default() {
if context
.sql
.get_config_int(context, "folders_configured")
.unwrap_or_default()
< 3
let dest_folder = context.sql.get_config(context, "configured_mvbox_folder");
if let Some(dest_folder) = dest_folder {
let mut dest_uid = 0;
if ImapResult::RetryLater
== inbox.mv(context, folder, uid, dest_folder, &mut dest_uid)
{
inbox.configure_folders(context, 0x1i32);
}
let dest_folder = context.sql.get_config(context, "configured_mvbox_folder");
if let Some(dest_folder) = dest_folder {
if ImapResult::RetryLater
== inbox.mv(context, folder, uid, dest_folder, &mut dest_uid)
{
self.try_again_later(3, None);
}
self.try_again_later(3, None);
}
}
}
@@ -863,7 +824,12 @@ fn job_perform(context: &Context, thread: Thread, probe_network: bool) {
Action::MoveMsg => job.do_DC_JOB_MOVE_MSG(context),
Action::SendMdn => job.do_DC_JOB_SEND(context),
Action::ConfigureImap => unsafe { dc_job_do_DC_JOB_CONFIGURE_IMAP(context) },
Action::ImexImap => unsafe { dc_job_do_DC_JOB_IMEX_IMAP(context, &job) },
Action::ImexImap => match dc_job_do_DC_JOB_IMEX_IMAP(context, &job) {
Ok(()) => {}
Err(err) => {
error!(context, "{}", err);
}
},
Action::MaybeSendLocations => {
location::job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context, &job)
}

View File

@@ -2,8 +2,6 @@ use std::path::{Path, PathBuf};
use std::ptr;
use deltachat_derive::{FromSql, ToSql};
use libc::{free, strcmp};
use phf::phf_map;
use crate::chat::{self, Chat};
use crate::constants::*;
@@ -109,18 +107,6 @@ impl Message {
msg.hidden = row.get(18)?;
msg.location_id = row.get(19)?;
msg.chat_blocked = row.get::<_, Option<Blocked>>(20)?.unwrap_or_default();
if msg.chat_blocked == Blocked::Deaddrop {
if let Some(ref text) = msg.text {
unsafe {
let ptr = text.strdup();
dc_truncate_n_unwrap_str(ptr, 256, 0);
msg.text = Some(to_string(ptr));
free(ptr.cast());
}
}
};
Ok(msg)
})
}
@@ -144,16 +130,18 @@ impl Message {
}
}
pub fn get_filemime(&self) -> String {
pub fn get_filemime(&self) -> Option<String> {
if let Some(m) = self.param.get(Param::MimeType) {
return m.to_string();
return Some(m.to_string());
} else if let Some(file) = self.param.get(Param::File) {
if let Some((_, mime)) = guess_msgtype_from_suffix(Path::new(file)) {
return mime.to_string();
return Some(mime.to_string());
}
// we have a file but no mimetype, let's use a generic one
return Some("application/octet-stream".to_string());
}
"application/octet-stream".to_string()
// no mimetype and no file
None
}
pub fn get_file(&self, context: &Context) -> Option<PathBuf> {
@@ -346,7 +334,7 @@ impl Message {
}
pub fn get_setupcodebegin(&self, context: &Context) -> Option<String> {
if self.is_setupmessage() {
if !self.is_setupmessage() {
return None;
}
@@ -354,7 +342,7 @@ impl Message {
if let Ok(mut buf) = dc_read_file(context, filename) {
unsafe {
// just a pointer inside buf, MUST NOT be free()'d
let mut buf_headerline = ptr::null();
let mut buf_headerline = String::default();
// just a pointer inside buf, MUST NOT be free()'d
let mut buf_setupcodebegin = ptr::null();
@@ -364,10 +352,7 @@ impl Message {
&mut buf_setupcodebegin,
ptr::null_mut(),
ptr::null_mut(),
) && strcmp(
buf_headerline,
b"-----BEGIN PGP MESSAGE-----\x00" as *const u8 as *const libc::c_char,
) == 0
) && buf_headerline == "-----BEGIN PGP MESSAGE-----"
&& !buf_setupcodebegin.is_null()
{
return Some(to_string(buf_setupcodebegin));
@@ -647,7 +632,7 @@ pub fn get_msg_info(context: &Context, msg_id: u32) -> String {
ret += "Type: ";
ret += &format!("{}", msg.type_0);
ret += "\n";
ret += &format!("Mimetype: {}\n", &msg.get_filemime());
ret += &format!("Mimetype: {}\n", &msg.get_filemime().unwrap_or_default());
}
let w = msg.param.get_int(Param::Width).unwrap_or_default();
let h = msg.param.get_int(Param::Height).unwrap_or_default();
@@ -674,22 +659,24 @@ pub fn get_msg_info(context: &Context, msg_id: u32) -> String {
}
pub fn guess_msgtype_from_suffix(path: &Path) -> Option<(Viewtype, &str)> {
static KNOWN: phf::Map<&'static str, (Viewtype, &'static str)> = phf_map! {
"mp3" => (Viewtype::Audio, "audio/mpeg"),
"aac" => (Viewtype::Audio, "audio/aac"),
"mp4" => (Viewtype::Video, "video/mp4"),
"jpg" => (Viewtype::Image, "image/jpeg"),
"jpeg" => (Viewtype::Image, "image/jpeg"),
"jpe" => (Viewtype::Image, "image/jpeg"),
"png" => (Viewtype::Image, "image/png"),
"webp" => (Viewtype::Image, "image/webp"),
"gif" => (Viewtype::Gif, "image/gif"),
"vcf" => (Viewtype::File, "text/vcard"),
"vcard" => (Viewtype::File, "text/vcard"),
};
let extension: &str = &path.extension()?.to_str()?.to_lowercase();
KNOWN.get(extension).map(|x| *x)
let info = match extension {
"mp3" => (Viewtype::Audio, "audio/mpeg"),
"aac" => (Viewtype::Audio, "audio/aac"),
"mp4" => (Viewtype::Video, "video/mp4"),
"jpg" => (Viewtype::Image, "image/jpeg"),
"jpeg" => (Viewtype::Image, "image/jpeg"),
"jpe" => (Viewtype::Image, "image/jpeg"),
"png" => (Viewtype::Image, "image/png"),
"webp" => (Viewtype::Image, "image/webp"),
"gif" => (Viewtype::Gif, "image/gif"),
"vcf" => (Viewtype::File, "text/vcard"),
"vcard" => (Viewtype::File, "text/vcard"),
_ => {
return None;
}
};
Some(info)
}
pub fn get_mime_headers(context: &Context, msg_id: u32) -> Option<String> {
@@ -1156,5 +1143,6 @@ mod tests {
let msg_id = chat::prepare_msg(ctx, chat, &mut msg).unwrap();
let _msg2 = Message::load_from_db(ctx, msg_id).unwrap();
assert_eq!(_msg2.get_filemime(), None);
}
}

View File

@@ -3,12 +3,12 @@ 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::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::*;
@@ -86,7 +86,7 @@ impl<'a> MimeFactory<'a> {
pub fn finalize_mime_message(
&mut self,
message: *mut mailmime,
message: *mut Mailmime,
encrypted: bool,
gossiped: bool,
) -> Result<(), Error> {
@@ -236,12 +236,12 @@ impl<'a> MimeFactory<'a> {
);
}
let cleanup = |message: *mut mailmime| {
let cleanup = |message: *mut Mailmime| {
if !message.is_null() {
mailmime_free(message);
}
};
let message = mailmime_new_message_data(0 as *mut mailmime);
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);
@@ -257,7 +257,7 @@ impl<'a> MimeFactory<'a> {
/* Render a normal message
*********************************************************************/
let chat = self.chat.as_ref().unwrap();
let mut meta_part: *mut mailmime = ptr::null_mut();
let mut meta_part: *mut Mailmime = ptr::null_mut();
let mut placeholdertext = None;
if chat.typ == Chattype::VerifiedGroup {
@@ -589,7 +589,7 @@ impl<'a> MimeFactory<'a> {
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 =
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);
@@ -821,7 +821,7 @@ fn build_body_file(
context: &Context,
msg: &Message,
base_name: &str,
) -> Result<(*mut mailmime, String), Error> {
) -> Result<(*mut Mailmime, String), Error> {
let path_filename = match msg.param.get(Param::File) {
None => {
bail!("msg has no filename");

View File

@@ -19,7 +19,7 @@ use crate::keyring::*;
pub unsafe fn dc_split_armored_data(
buf: *mut libc::c_char,
ret_headerline: *mut *const libc::c_char,
ret_headerline: *mut String,
ret_setupcodebegin: *mut *const libc::c_char,
ret_preferencrypt: *mut *const libc::c_char,
ret_base64: *mut *const libc::c_char,
@@ -31,9 +31,6 @@ pub unsafe fn dc_split_armored_data(
let mut p2: *mut libc::c_char;
let mut headerline: *mut libc::c_char = ptr::null_mut();
let mut base64: *mut libc::c_char = ptr::null_mut();
if !ret_headerline.is_null() {
*ret_headerline = ptr::null()
}
if !ret_setupcodebegin.is_null() {
*ret_setupcodebegin = ptr::null_mut();
}
@@ -43,7 +40,7 @@ pub unsafe fn dc_split_armored_data(
if !ret_base64.is_null() {
*ret_base64 = ptr::null();
}
if !(buf.is_null() || ret_headerline.is_null()) {
if !buf.is_null() {
dc_remove_cr_chars(buf);
while 0 != *p1 {
if *p1 as libc::c_int == '\n' as i32 {
@@ -62,9 +59,7 @@ pub unsafe fn dc_split_armored_data(
) == 0i32
{
headerline = line;
if !ret_headerline.is_null() {
*ret_headerline = headerline
}
*ret_headerline = as_str(headerline).to_string();
}
} else if strspn(line, b"\t\r\n \x00" as *const u8 as *const libc::c_char)
== strlen(line)

View File

@@ -522,7 +522,9 @@ pub fn handle_securejoin_handshake(
error!(context, "Chat {} not found.", &field_grpid);
return ret;
} else {
if let Err(err) = chat::add_contact_to_chat_ex(context, group_chat_id, contact_id, true) {
if let Err(err) =
chat::add_contact_to_chat_ex(context, group_chat_id, contact_id, true)
{
error!(context, "failed to add contact: {}", err);
}
}

View File

@@ -70,8 +70,9 @@ impl Smtp {
let port = lp.send_port as u16;
let tls = native_tls::TlsConnector::builder()
// FIXME: unfortunately this is needed to make things work on macos + testrun.org
// see also: https://github.com/deltachat/deltachat-core-rust/issues/203
.danger_accept_invalid_hostnames(true)
.danger_accept_invalid_certs(true)
.min_protocol_version(Some(DEFAULT_TLS_PROTOCOLS[0]))
.build()
.unwrap();

View File

@@ -3,12 +3,12 @@ use std::ffi::CString;
use crate::dc_tools::*;
use crate::error::Error;
use mmime::clist::*;
use mmime::mailimf_types::*;
use mmime::mailimf_types_helper::*;
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::*;
use mmime::mailmime_disposition::*;
use mmime::mailmime_types::*;
use mmime::mailmime_types_helper::*;
use mmime::other::*;
#[macro_export]
@@ -26,7 +26,7 @@ macro_rules! clist_append {
}
pub fn add_filename_part(
message: *mut mailmime,
message: *mut Mailmime,
basename: &str,
mime_type: &str,
file_content: &str,
@@ -57,9 +57,9 @@ pub fn new_custom_field(fields: *mut mailimf_fields, name: &str, value: &str) {
}
}
pub fn build_body_text(text: &str) -> Result<*mut mailmime, Error> {
pub fn build_body_text(text: &str) -> Result<*mut Mailmime, Error> {
let mime_fields: *mut mailmime_fields;
let message_part: *mut mailmime;
let message_part: *mut Mailmime;
let content = new_content_type("text/plain")?;
append_ct_param(content, "charset", "utf-8")?;
@@ -104,7 +104,7 @@ pub fn new_content_type(content_type: &str) -> Result<*mut mailmime_content, Err
Ok(content)
}
pub fn set_body_text(part: *mut mailmime, text: &str) -> Result<(), Error> {
pub fn set_body_text(part: *mut Mailmime, text: &str) -> Result<(), Error> {
use libc::strlen;
unsafe {
let text_c = text.strdup();

View File

@@ -59,7 +59,7 @@ unsafe fn stress_functions(context: &Context) {
assert!(res.contains(" configured_server_flags "));
let mut buf_0: *mut libc::c_char;
let mut headerline: *const libc::c_char = ptr::null();
let mut headerline = String::default();
let mut setupcodebegin: *const libc::c_char = ptr::null();
let mut preferencrypt: *const libc::c_char = ptr::null();
let mut base64: *const libc::c_char = ptr::null();
@@ -75,14 +75,8 @@ unsafe fn stress_functions(context: &Context) {
&mut base64,
);
assert!(ok);
assert!(!headerline.is_null());
assert_eq!(
strcmp(
headerline,
b"-----BEGIN PGP MESSAGE-----\x00" as *const u8 as *const libc::c_char,
),
0
);
assert!(!headerline.is_empty());
assert_eq!(headerline, "-----BEGIN PGP MESSAGE-----");
assert!(!base64.is_null());
assert_eq!(as_str(base64 as *const libc::c_char), "data",);
@@ -101,14 +95,7 @@ unsafe fn stress_functions(context: &Context) {
);
assert!(ok);
assert!(!headerline.is_null());
assert_eq!(
strcmp(
headerline,
b"-----BEGIN PGP MESSAGE-----\x00" as *const u8 as *const libc::c_char,
),
0
);
assert_eq!(headerline, "-----BEGIN PGP MESSAGE-----");
assert!(!base64.is_null());
assert_eq!(as_str(base64 as *const libc::c_char), "dat1",);
@@ -128,14 +115,7 @@ unsafe fn stress_functions(context: &Context) {
);
assert!(ok);
assert!(!headerline.is_null());
assert_eq!(
strcmp(
headerline,
b"-----BEGIN PGP MESSAGE-----\x00" as *const u8 as *const libc::c_char,
),
0
);
assert_eq!(headerline, "-----BEGIN PGP MESSAGE-----");
assert!(setupcodebegin.is_null());
assert!(!base64.is_null());
@@ -165,14 +145,7 @@ unsafe fn stress_functions(context: &Context) {
&mut base64,
);
assert!(ok);
assert!(!headerline.is_null());
assert_eq!(
strcmp(
headerline,
b"-----BEGIN PGP MESSAGE-----\x00" as *const u8 as *const libc::c_char,
),
0
);
assert_eq!(headerline, "-----BEGIN PGP MESSAGE-----");
assert!(!setupcodebegin.is_null());
assert_eq!(
@@ -199,15 +172,7 @@ unsafe fn stress_functions(context: &Context) {
&mut base64,
);
assert!(ok);
assert!(!headerline.is_null());
assert_eq!(
strcmp(
headerline,
b"-----BEGIN PGP PRIVATE KEY BLOCK-----\x00" as *const u8 as *const libc::c_char,
),
0
);
assert_eq!(headerline, "-----BEGIN PGP PRIVATE KEY BLOCK-----");
assert!(!preferencrypt.is_null());
assert_eq!(
strcmp(
@@ -222,35 +187,8 @@ unsafe fn stress_functions(context: &Context) {
free(buf_0 as *mut libc::c_void);
let mut norm: *mut libc::c_char = dc_normalize_setup_code(
context,
b"123422343234423452346234723482349234\x00" as *const u8 as *const libc::c_char,
);
assert!(!norm.is_null());
assert_eq!(
0,
strcmp(
norm,
b"1234-2234-3234-4234-5234-6234-7234-8234-9234\x00" as *const u8 as *const libc::c_char,
)
);
free(norm as *mut libc::c_void);
norm = dc_normalize_setup_code(
context,
b"\t1 2 3422343234- foo bar-- 423-45 2 34 6234723482349234 \x00" as *const u8
as *const libc::c_char,
);
assert!(!norm.is_null());
assert_eq!(
0,
strcmp(
norm,
b"1234-2234-3234-4234-5234-6234-7234-8234-9234\x00" as *const u8 as *const libc::c_char,
)
);
free(norm as *mut libc::c_void);
let mut buf_1: *mut libc::c_char;
let mut headerline_0: *const libc::c_char = ptr::null();
let mut headerline_0 = String::default();
let mut setupcodebegin_0: *const libc::c_char = ptr::null();
let mut preferencrypt_0: *const libc::c_char = ptr::null();
buf_1 = strdup(S_EM_SETUPFILE);
@@ -261,14 +199,7 @@ unsafe fn stress_functions(context: &Context) {
&mut preferencrypt_0,
ptr::null_mut(),
));
assert!(!headerline_0.is_null());
assert_eq!(
0,
strcmp(
headerline_0,
b"-----BEGIN PGP MESSAGE-----\x00" as *const u8 as *const libc::c_char,
)
);
assert_eq!(headerline_0, "-----BEGIN PGP MESSAGE-----");
assert!(!setupcodebegin_0.is_null());
assert!(strlen(setupcodebegin_0) < strlen(S_EM_SETUPCODE));
assert_eq!(
@@ -278,7 +209,8 @@ unsafe fn stress_functions(context: &Context) {
assert!(preferencrypt_0.is_null());
free(buf_1 as *mut libc::c_void);
buf_1 = dc_decrypt_setup_file(context, S_EM_SETUPCODE, S_EM_SETUPFILE);
let decrypted = dc_decrypt_setup_file(context, S_EM_SETUPCODE, S_EM_SETUPFILE).unwrap();
buf_1 = decrypted.strdup();
assert!(!buf_1.is_null());
assert!(dc_split_armored_data(
buf_1,
@@ -287,14 +219,7 @@ unsafe fn stress_functions(context: &Context) {
&mut preferencrypt_0,
ptr::null_mut(),
));
assert!(!headerline_0.is_null());
assert_eq!(
strcmp(
headerline_0,
b"-----BEGIN PGP PRIVATE KEY BLOCK-----\x00" as *const u8 as *const libc::c_char,
),
0
);
assert_eq!(headerline_0, "-----BEGIN PGP PRIVATE KEY BLOCK-----");
assert!(setupcodebegin_0.is_null());
assert!(!preferencrypt_0.is_null());
assert_eq!(