diff --git a/.circleci/config.yml b/.circleci/config.yml index c2abf887c..d57938e67 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,49 +1,149 @@ -# copied from http://koushiro.me/2019/04/30/Building-and-Testing-Rust-projects-on-CircleCI/ - version: 2.1 -jobs: - build: + +executors: + default: docker: - - image: ubuntu:18.04 + - image: filecoin/rust:latest + working_directory: /mnt/crate - working_directory: ~/deltachat-core-rust +restore-workspace: &restore-workspace + attach_workspace: + at: /mnt +restore-cache: &restore-cache + restore_cache: + keys: + - cargo-v0-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }} + - repo-source-{{ .Branch }}-{{ .Revision }} + +commands: + test_target: + parameters: + target: + type: string + steps: + - *restore-workspace + - *restore-cache + - setup_remote_docker: + docker_layer_caching: true + # TODO: move into image + - run: + name: Install Docker client + command: | + set -x + VER="18.09.2" + curl -L -o /tmp/docker-$VER.tgz https://download.docker.com/linux/static/stable/x86_64/docker-$VER.tgz + tar -xz -C /tmp -f /tmp/docker-$VER.tgz + mv /tmp/docker/* /usr/bin + - run: + name: Test (<< parameters.target >>) + command: TARGET=<< parameters.target >> ci/run.sh + no_output_timeout: 15m + +jobs: + cargo_fetch: + executor: default steps: - checkout - - run: - name: Setup build environment - command: | - apt update - apt install -y curl build-essential autoconf libtool git python pkg-config libssl-dev - # this will pick default toolchain from `rust-toolchain` file - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --no-modify-path --default-toolchain none -y; - source $HOME/.cargo/env - no_output_timeout: 1800s - + name: Update submodules + command: git submodule update --init --recursive - run: - name: Format - command: | - export PATH=~/.cargo/bin:$PATH - rustup component add rustfmt - cargo fmt -- --check + name: Calculate dependencies + command: cargo generate-lockfile + - restore_cache: + keys: + - cargo-v0-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }} + - run: rustup install $(cat rust-toolchain) + - run: rustup default $(cat rust-toolchain) + - run: rustup component add --toolchain $(cat rust-toolchain) rustfmt + - run: cargo update + - run: cargo fetch + - run: rustc +stable --version + - run: rustc +$(cat rust-toolchain) --version + - run: rm -rf .git + - persist_to_workspace: + root: /mnt + paths: + - crate + - save_cache: + key: cargo-v0-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }} + paths: + - "~/.cargo" + - "~/.rustup" + rustfmt: + executor: default + steps: + - *restore-workspace + - *restore-cache + - run: + name: Run cargo fmt + command: cargo fmt --all -- --check + + test_macos: + macos: + xcode: "10.0.0" + working_directory: ~/crate + steps: + - run: + name: Configure environment variables + command: | + echo 'export PATH="${HOME}/.cargo/bin:${HOME}/.bin:${PATH}"' >> $BASH_ENV + echo 'export CIRCLE_ARTIFACTS="/tmp"' >> $BASH_ENV + - checkout + - run: + name: Install Rust + command: | + curl https://sh.rustup.rs -sSf | sh -s -- -y + - run: rustup install $(cat rust-toolchain) + - run: rustup default $(cat rust-toolchain) + - run: cargo update + - run: cargo fetch - run: name: Test - command: | - export PATH=~/.cargo/bin:$PATH - export RUST_BACKTRACE=1 - cargo test + command: TARGET=x86_64-apple-darwin ci/run.sh + + test_x86_64-unknown-linux-gnu: + executor: default + steps: + - test_target: + target: "x86_64-unknown-linux-gnu" + + test_i686-unknown-linux-gnu: + executor: default + steps: + - test_target: + target: "i686-unknown-linux-gnu" + + test_aarch64-linux-android: + executor: default + steps: + - test_target: + target: "aarch64-linux-android" - - run: - name: Build deltachat-ffi - command: | - export PATH=~/.cargo/bin:$PATH - export RUST_BACKTRACE=1 - cargo build --release -p deltachat_ffi workflows: version: 2.1 - build: + + test: jobs: - - build + - cargo_fetch + - rustfmt: + requires: + - cargo_fetch + + # Linux Desktop + - test_x86_64-unknown-linux-gnu: + requires: + - cargo_fetch + + # Linux Desktop + # - test_aarch64-linux-android: + # requires: + # - cargo_fetch + + # Desktop Apple + # - test_macos: + # requires: + # - cargo_fetch diff --git a/Cargo.toml b/Cargo.toml index 7f1dffd1b..80f68ab1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,12 +10,12 @@ pkg-config = "0.3" [dependencies] libc = "0.2.51" -pgp = "0.2.0" +pgp = "0.2" hex = "0.3.2" sha2 = "0.8.0" rand = "0.6.5" smallvec = "0.6.9" -libsqlite3-sys = { version = "0.14.0", features = ["bundled"] } +libsqlite3-sys = { version = "0.14.0", features = ["bundled", "min_sqlite_version_3_7_16"] } reqwest = "0.9.15" num-derive = "0.2.5" num-traits = "0.2.6" @@ -28,6 +28,7 @@ charset = "0.1" percent-encoding = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +chrono = "0.4.6" [dev-dependencies] tempfile = "3.0" @@ -46,5 +47,6 @@ path = "examples/repl/main.rs" [features] -default = [] -vendored = ["native-tls/vendored"] +default = ["nightly"] +vendored = ["native-tls/vendored", "reqwest/default-tls-vendored"] +nightly = ["pgp/nightly"] diff --git a/ci/run.sh b/ci/run.sh new file mode 100755 index 000000000..1ee9317d7 --- /dev/null +++ b/ci/run.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -ex + +export RUST_TEST_THREADS=1 +export RUST_BACKTRACE=1 +export OPT="--target=$TARGET" +export OPT_RELEASE="--release ${OPT}" +export OPT_FFI_RELEASE="--manifest-path=deltachat-ffi/Cargo.toml --release" + +# Select cargo command: use cross by default +export CARGO_CMD=cross + +# On Appveyor (windows) and Travis (x86_64-unknown-linux-gnu and apple) native targets we use cargo (no need to cross-compile): +if [[ $TARGET = *"windows"* ]] || [[ $TARGET == "x86_64-unknown-linux-gnu" ]] || [[ $TARGET = *"apple"* ]]; then + export CARGO_CMD=cargo +fi + +# Install cross if necessary: +if [[ $CARGO_CMD == "cross" ]]; then + cargo install --git https://github.com/dignifiedquire/cross --rev fix-tty --force +fi + +# Make sure TARGET is installed when using cargo: +if [[ $CARGO_CMD == "cargo" ]]; then + rustup target add $TARGET || true +fi + +# If the build should not run tests, just check that the code builds: +if [[ $NORUN == "1" ]]; then + export CARGO_SUBCMD="build" +else + export CARGO_SUBCMD="test" + export OPT="${OPT} " + export OPT_RELEASE="${OPT_RELEASE} " +fi + +# Run all the test configurations: +$CARGO_CMD $CARGO_SUBCMD $OPT +$CARGO_CMD $CARGO_SUBCMD $OPT_RELEASE +$CARGO_CMD $CARGO_SUBCMD $OPT_RELEASE_IGNORED + +# Build the ffi lib +$CARGO_CMD $CARGO_SUBCMD $OPT_FFI_RELEASE diff --git a/deltachat-ffi/Cargo.toml b/deltachat-ffi/Cargo.toml index 40578ce73..2459a590f 100644 --- a/deltachat-ffi/Cargo.toml +++ b/deltachat-ffi/Cargo.toml @@ -17,3 +17,6 @@ crate-type = ["cdylib", "staticlib"] [dependencies] deltachat = { path = "../" } libc = "0.2" + +[features] +default = ["deltachat/vendored"] \ No newline at end of file diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 654ef3381..f0509ea7d 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -339,7 +339,6 @@ dc_contact_t* dc_get_contact (dc_context_t*, uint32_t contact_id #define DC_IMEX_IMPORT_BACKUP 12 // param1 is the file with the backup to import void dc_imex (dc_context_t*, int what, const char* param1, const char* param2); char* dc_imex_has_backup (dc_context_t*, const char* dir); -int dc_check_password (dc_context_t*, const char* pw); char* dc_initiate_key_transfer (dc_context_t*); int dc_continue_key_transfer (dc_context_t*, uint32_t msg_id, const char* setup_code); void dc_stop_ongoing_process (dc_context_t*); @@ -364,7 +363,7 @@ uint32_t dc_join_securejoin (dc_context_t*, const char* qr); void dc_send_locations_to_chat (dc_context_t*, uint32_t chat_id, int seconds); int dc_is_sending_locations_to_chat (dc_context_t*, uint32_t chat_id); int dc_set_location (dc_context_t*, double latitude, double longitude, double accuracy); -dc_array_t* dc_get_locations (dc_context_t*, uint32_t chat_id, uint32_t contact_id, time_t timestamp_begin, time_t timestamp_end); +dc_array_t* dc_get_locations (dc_context_t*, uint32_t chat_id, uint32_t contact_id, int64_t timestamp_begin, int64_t timestamp_end); void dc_delete_all_locations (dc_context_t*); @@ -389,7 +388,7 @@ void* dc_array_get_ptr (const dc_array_t*, size_t index); double dc_array_get_latitude (const dc_array_t*, size_t index); double dc_array_get_longitude (const dc_array_t*, size_t index); double dc_array_get_accuracy (const dc_array_t*, size_t index); -time_t dc_array_get_timestamp (const dc_array_t*, size_t index); +int64_t dc_array_get_timestamp (const dc_array_t*, size_t index); uint32_t dc_array_get_chat_id (const dc_array_t*, size_t index); uint32_t dc_array_get_contact_id (const dc_array_t*, size_t index); uint32_t dc_array_get_msg_id (const dc_array_t*, size_t index); @@ -524,9 +523,9 @@ uint32_t dc_msg_get_from_id (const dc_msg_t*); uint32_t dc_msg_get_chat_id (const dc_msg_t*); int dc_msg_get_viewtype (const dc_msg_t*); int dc_msg_get_state (const dc_msg_t*); -time_t dc_msg_get_timestamp (const dc_msg_t*); -time_t dc_msg_get_received_timestamp (const dc_msg_t*); -time_t dc_msg_get_sort_timestamp (const dc_msg_t*); +int64_t dc_msg_get_timestamp (const dc_msg_t*); +int64_t dc_msg_get_received_timestamp (const dc_msg_t*); +int64_t dc_msg_get_sort_timestamp (const dc_msg_t*); char* dc_msg_get_text (const dc_msg_t*); char* dc_msg_get_file (const dc_msg_t*); char* dc_msg_get_filename (const dc_msg_t*); @@ -617,7 +616,7 @@ char* dc_lot_get_text2 (const dc_lot_t*); int dc_lot_get_text1_meaning (const dc_lot_t*); int dc_lot_get_state (const dc_lot_t*); uint32_t dc_lot_get_id (const dc_lot_t*); -time_t dc_lot_get_timestamp (const dc_lot_t*); +int64_t dc_lot_get_timestamp (const dc_lot_t*); /** diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 6ff7fcaae..0288fcb33 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -917,13 +917,19 @@ pub unsafe extern "C" fn dc_get_locations( context: *mut dc_context_t, chat_id: libc::uint32_t, contact_id: libc::uint32_t, - timestamp_begin: libc::time_t, - timestamp_end: libc::time_t, + timestamp_begin: i64, + timestamp_end: i64, ) -> *mut dc_array::dc_array_t { assert!(!context.is_null()); let context = &*context; - dc_location::dc_get_locations(context, chat_id, contact_id, timestamp_begin, timestamp_end) + dc_location::dc_get_locations( + context, + chat_id, + contact_id, + timestamp_begin as i64, + timestamp_end as i64, + ) } #[no_mangle] @@ -1007,7 +1013,7 @@ pub unsafe extern "C" fn dc_array_get_accuracy( pub unsafe extern "C" fn dc_array_get_timestamp( array: *const dc_array_t, index: libc::size_t, -) -> libc::time_t { +) -> i64 { dc_array::dc_array_get_timestamp(array, index) } #[no_mangle] @@ -1232,17 +1238,17 @@ pub unsafe extern "C" fn dc_msg_get_state(msg: *mut dc_msg::dc_msg_t) -> libc::c } #[no_mangle] -pub unsafe extern "C" fn dc_msg_get_timestamp(msg: *mut dc_msg::dc_msg_t) -> libc::time_t { +pub unsafe extern "C" fn dc_msg_get_timestamp(msg: *mut dc_msg::dc_msg_t) -> i64 { dc_msg::dc_msg_get_timestamp(msg) } #[no_mangle] -pub unsafe extern "C" fn dc_msg_get_received_timestamp(msg: *mut dc_msg::dc_msg_t) -> libc::time_t { +pub unsafe extern "C" fn dc_msg_get_received_timestamp(msg: *mut dc_msg::dc_msg_t) -> i64 { dc_msg::dc_msg_get_received_timestamp(msg) } #[no_mangle] -pub unsafe extern "C" fn dc_msg_get_sort_timestamp(msg: *mut dc_msg::dc_msg_t) -> libc::time_t { +pub unsafe extern "C" fn dc_msg_get_sort_timestamp(msg: *mut dc_msg::dc_msg_t) -> i64 { dc_msg::dc_msg_get_sort_timestamp(msg) } @@ -1527,6 +1533,6 @@ pub unsafe extern "C" fn dc_lot_get_id(lot: *mut dc_lot::dc_lot_t) -> libc::uint } #[no_mangle] -pub unsafe extern "C" fn dc_lot_get_timestamp(lot: *mut dc_lot::dc_lot_t) -> libc::time_t { +pub unsafe extern "C" fn dc_lot_get_timestamp(lot: *mut dc_lot::dc_lot_t) -> i64 { dc_lot::dc_lot_get_timestamp(lot) } diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 3d8359ac1..7d55d79b1 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -1098,8 +1098,8 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char context, dc_chat_get_id(sel_chat), contact_id_2 as uint32_t, - 0i32 as time_t, - 0i32 as time_t, + 0, + 0, ); let mut j = 0; while j < dc_array_get_cnt(loc) { diff --git a/src/context.rs b/src/context.rs index fbeef72de..6c9cdeba9 100644 --- a/src/context.rs +++ b/src/context.rs @@ -40,7 +40,7 @@ pub struct Context { pub os_name: *mut libc::c_char, pub cmdline_sel_chat_id: Arc>, pub bob: Arc>, - pub last_smeared_timestamp: Arc>, + pub last_smeared_timestamp: Arc>, pub running_state: Arc>, } @@ -114,7 +114,7 @@ pub struct _dc_location { pub latitude: libc::c_double, pub longitude: libc::c_double, pub accuracy: libc::c_double, - pub timestamp: time_t, + pub timestamp: i64, pub contact_id: uint32_t, pub msg_id: uint32_t, pub chat_id: uint32_t, @@ -148,7 +148,7 @@ pub fn dc_context_new( smtp_state: Arc::new((Mutex::new(Default::default()), Condvar::new())), oauth2_critical: Arc::new(Mutex::new(())), bob: Arc::new(RwLock::new(Default::default())), - last_smeared_timestamp: Arc::new(RwLock::new(0 as time_t)), + last_smeared_timestamp: Arc::new(RwLock::new(0)), cmdline_sel_chat_id: Arc::new(RwLock::new(0)), sentbox_thread: Arc::new(RwLock::new(unsafe { dc_jobthread_init( diff --git a/src/dc_array.rs b/src/dc_array.rs index f3b6c5e01..3ef41e7a0 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -146,14 +146,14 @@ pub unsafe fn dc_array_get_accuracy(array: *const dc_array_t, index: size_t) -> (*(*(*array).array.offset(index as isize) as *mut _dc_location)).accuracy } -pub unsafe fn dc_array_get_timestamp(array: *const dc_array_t, index: size_t) -> time_t { +pub unsafe fn dc_array_get_timestamp(array: *const dc_array_t, index: size_t) -> i64 { if array.is_null() || (*array).magic != 0xa11aai32 as libc::c_uint || index >= (*array).count || (*array).type_0 != 1i32 || *(*array).array.offset(index as isize) == 0 { - return 0i32 as time_t; + return 0; } (*(*(*array).array.offset(index as isize) as *mut _dc_location)).timestamp } diff --git a/src/dc_chat.rs b/src/dc_chat.rs index 07bfb3c81..7a6d5cf0f 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -27,7 +27,7 @@ pub struct dc_chat_t<'a> { pub grpid: *mut libc::c_char, pub blocked: libc::c_int, pub param: *mut dc_param_t, - pub gossiped_timestamp: time_t, + pub gossiped_timestamp: i64, pub is_sending_locations: libc::c_int, } @@ -108,7 +108,7 @@ pub unsafe fn dc_chat_empty(mut chat: *mut dc_chat_t) { free((*chat).grpid as *mut libc::c_void); (*chat).grpid = 0 as *mut libc::c_char; (*chat).blocked = 0i32; - (*chat).gossiped_timestamp = 0i32 as time_t; + (*chat).gossiped_timestamp = 0; dc_param_set_packed((*chat).param, 0 as *const libc::c_char); } @@ -185,11 +185,11 @@ unsafe fn set_from_stmt(mut chat: *mut dc_chat_t, row: *mut sqlite3_stmt) -> lib (*chat).blocked = sqlite3_column_int(row, fresh6); let fresh7 = row_offset; row_offset = row_offset + 1; - (*chat).gossiped_timestamp = sqlite3_column_int64(row, fresh7) as time_t; + (*chat).gossiped_timestamp = sqlite3_column_int64(row, fresh7) as i64; let fresh8 = row_offset; row_offset = row_offset + 1; (*chat).is_sending_locations = - (sqlite3_column_int64(row, fresh8) > time(0 as *mut time_t)) as libc::c_int; + (sqlite3_column_int64(row, fresh8) as i64 > time()) as libc::c_int; if (*chat).id == 1i32 as libc::c_uint { free((*chat).name as *mut libc::c_void); (*chat).name = dc_stock_str((*chat).context, 8i32) @@ -530,7 +530,7 @@ unsafe fn prepare_msg_raw( context: &Context, chat: *mut dc_chat_t, msg: *const dc_msg_t, - timestamp: time_t, + timestamp: i64, ) -> uint32_t { let mut do_guarantee_e2ee: libc::c_int; let e2ee_enabled: libc::c_int; @@ -1141,7 +1141,7 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t *const libc::c_char); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); sqlite3_bind_int(stmt, 2i32, 1i32); - sqlite3_bind_int64(stmt, 3i32, time(0 as *mut time_t) as sqlite3_int64); + sqlite3_bind_int64(stmt, 3i32, time() as sqlite3_int64); sqlite3_bind_int(stmt, 4i32, (*msg).type_0); sqlite3_bind_int(stmt, 5i32, 19i32); sqlite3_bind_text( @@ -1214,7 +1214,7 @@ pub unsafe fn dc_get_chat_msgs( let ret: *mut dc_array_t = dc_array_new(512i32 as size_t); let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; let mut curr_id: uint32_t; - let mut curr_local_timestamp: time_t; + let mut curr_local_timestamp: i64; let mut curr_day: libc::c_int; let mut last_day = 0; let cnv_to_local = dc_gm2local_offset(); @@ -1252,7 +1252,8 @@ pub unsafe fn dc_get_chat_msgs( dc_array_add_id(ret, 1i32 as uint32_t); } if 0 != flags & 0x1i32 as libc::c_uint { - curr_local_timestamp = sqlite3_column_int64(stmt, 1i32) as time_t + cnv_to_local; + curr_local_timestamp = + (sqlite3_column_int64(stmt, 1i32) as i64 + cnv_to_local) as i64; curr_day = (curr_local_timestamp / 86400) as libc::c_int; if curr_day != last_day { dc_array_add_id(ret, 9i32 as uint32_t); @@ -1828,10 +1829,10 @@ unsafe fn real_group_exists(context: &Context, chat_id: uint32_t) -> libc::c_int } pub unsafe fn dc_reset_gossiped_timestamp(context: &Context, chat_id: uint32_t) { - dc_set_gossiped_timestamp(context, chat_id, 0i32 as time_t); + dc_set_gossiped_timestamp(context, chat_id, 0); } -pub unsafe fn dc_set_gossiped_timestamp(context: &Context, chat_id: uint32_t, timestamp: time_t) { +pub unsafe fn dc_set_gossiped_timestamp(context: &Context, chat_id: uint32_t, timestamp: i64) { let stmt: *mut sqlite3_stmt; if 0 != chat_id { dc_log_info( @@ -2149,7 +2150,7 @@ pub unsafe fn dc_forward_msgs( let mut idsstr: *mut libc::c_char = 0 as *mut libc::c_char; let mut q3: *mut libc::c_char = 0 as *mut libc::c_char; let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; - let mut curr_timestamp: time_t; + let mut curr_timestamp: i64; let original_param: *mut dc_param_t = dc_param_new(); if !(msg_ids.is_null() || msg_cnt <= 0i32 || chat_id <= 9i32 as libc::c_uint) { dc_unarchive_chat(context, chat_id); diff --git a/src/dc_configure.rs b/src/dc_configure.rs index f0aeccdff..440da30b4 100644 --- a/src/dc_configure.rs +++ b/src/dc_configure.rs @@ -1764,7 +1764,7 @@ pub unsafe fn dc_connect_to_configured_imap(context: &Context, imap: &Imap) -> l ); /*the trailing underscore is correct*/ if !(0 == imap.connect(context, param)) { - ret_connected = 2i32 + ret_connected = 2i32; } } dc_loginparam_unref(param); diff --git a/src/dc_e2ee.rs b/src/dc_e2ee.rs index 47863a70a..9c879f038 100644 --- a/src/dc_e2ee.rs +++ b/src/dc_e2ee.rs @@ -603,8 +603,8 @@ pub unsafe fn dc_e2ee_decrypt( let orig_date: *mut mailimf_orig_date = (*field).fld_data.fld_orig_date; if !orig_date.is_null() { message_time = dc_timestamp_from_date((*orig_date).dt_date_time); - if message_time != -1 && message_time > time(0 as *mut time_t) { - message_time = time(0 as *mut time_t) + if message_time != 0 && message_time > time() { + message_time = time() } } } @@ -699,7 +699,7 @@ pub unsafe fn dc_e2ee_decrypt( unsafe fn update_gossip_peerstates( context: &Context, - message_time: time_t, + message_time: i64, imffields: *mut mailimf_fields, gossip_headers: *const mailimf_fields, ) -> HashSet { diff --git a/src/dc_imex.rs b/src/dc_imex.rs index 77d6b91bd..146ded76f 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -12,7 +12,6 @@ use crate::dc_configure::*; use crate::dc_e2ee::*; use crate::dc_job::*; use crate::dc_log::*; -use crate::dc_loginparam::*; use crate::dc_msg::*; use crate::dc_param::*; use crate::dc_sqlite3::*; @@ -49,7 +48,7 @@ pub unsafe fn dc_imex_has_backup( dir_name: *const libc::c_char, ) -> *mut libc::c_char { let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; - let mut ret_backup_time: time_t = 0i32 as time_t; + let mut ret_backup_time = 0; let dir_handle: *mut DIR; let mut dir_entry: *mut dirent; let prefix_len = strlen(b"delta-chat\x00" as *const u8 as *const libc::c_char); @@ -97,12 +96,12 @@ pub unsafe fn dc_imex_has_backup( } let mut sql = dc_sqlite3_new(); if 0 != dc_sqlite3_open(context, &mut sql, curr_pathNfilename, 0x1i32) { - let curr_backup_time: time_t = dc_sqlite3_get_config_int( + let curr_backup_time = dc_sqlite3_get_config_int( context, &mut sql, b"backup_time\x00" as *const u8 as *const libc::c_char, 0i32, - ) as time_t; + ) as u64; if curr_backup_time > 0 && curr_backup_time > ret_backup_time { free(ret as *mut libc::c_void); ret = curr_pathNfilename; @@ -124,35 +123,6 @@ pub unsafe fn dc_imex_has_backup( ret } -pub unsafe fn dc_check_password(context: &Context, test_pw: *const libc::c_char) -> libc::c_int { - /* Check if the given password matches the configured mail_pw. - This is to prompt the user before starting eg. an export; this is mainly to avoid doing people bad thinkgs if they have short access to the device. - When we start supporting OAuth some day, we should think this over, maybe force the user to re-authenticate himself with the Android password. */ - let loginparam: *mut dc_loginparam_t = dc_loginparam_new(); - let mut success: libc::c_int = 0i32; - - dc_loginparam_read( - context, - loginparam, - &context.sql.clone().read().unwrap(), - b"configured_\x00" as *const u8 as *const libc::c_char, - ); - if ((*loginparam).mail_pw.is_null() - || *(*loginparam).mail_pw.offset(0isize) as libc::c_int == 0i32) - && (test_pw.is_null() || *test_pw.offset(0isize) as libc::c_int == 0i32) - { - success = 1i32 - } else if (*loginparam).mail_pw.is_null() || test_pw.is_null() { - success = 0i32 - } else if strcmp((*loginparam).mail_pw, test_pw) == 0i32 { - success = 1i32 - } - - dc_loginparam_unref(loginparam); - - success -} - pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char { let current_block: u64; let mut success: libc::c_int = 0i32; @@ -1141,7 +1111,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ let mut success: libc::c_int = 0i32; let mut closed: libc::c_int = 0i32; let dest_pathNfilename: *mut libc::c_char; - let mut now = time(0 as *mut time_t); + let now = time(); let mut dir_handle: *mut DIR = 0 as *mut DIR; let mut dir_entry: *mut dirent; let prefix_len = strlen(b"delta-chat\x00" as *const u8 as *const libc::c_char); @@ -1156,16 +1126,11 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ let mut dest_sql: Option = None; /* get a fine backup file name (the name includes the date so that multiple backup instances are possible) FIXME: we should write to a temporary file first and rename it on success. this would guarantee the backup is complete. however, currently it is not clear it the import exists in the long run (may be replaced by a restore-from-imap)*/ - let timeinfo: *mut tm; - let mut buffer: [libc::c_char; 256] = [0; 256]; - timeinfo = localtime(&mut now); - strftime( - buffer.as_mut_ptr(), - 256i32 as size_t, - b"delta-chat-%Y-%m-%d.bak\x00" as *const u8 as *const libc::c_char, - timeinfo, - ); - dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer.as_mut_ptr()); + let res = chrono::NaiveDateTime::from_timestamp(now as i64, 0) + .format("delta-chat-%Y-%m-%d.bak") + .to_string(); + let buffer = to_cstring(res); + dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer.as_ptr()); if dest_pathNfilename.is_null() { dc_log_error( context, diff --git a/src/dc_job.rs b/src/dc_job.rs index 157949555..bb5fe1cd1 100644 --- a/src/dc_job.rs +++ b/src/dc_job.rs @@ -1,7 +1,7 @@ use mmime::mmapstring::*; use std::ffi::CStr; -use std::time::{Duration, SystemTime}; +use std::time::Duration; use rand::{thread_rng, Rng}; @@ -40,8 +40,8 @@ pub struct dc_job_t { pub job_id: uint32_t, pub action: libc::c_int, pub foreign_id: uint32_t, - pub desired_timestamp: time_t, - pub added_timestamp: time_t, + pub desired_timestamp: i64, + pub added_timestamp: i64, pub tries: libc::c_int, pub param: *mut dc_param_t, pub try_again: libc::c_int, @@ -89,7 +89,7 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network: b"SELECT id, action, foreign_id, param, added_timestamp, desired_timestamp, tries FROM jobs WHERE thread=? AND desired_timestamp<=? ORDER BY action DESC, added_timestamp;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int64(select_stmt, 1i32, thread as sqlite3_int64); - sqlite3_bind_int64(select_stmt, 2i32, time(0 as *mut time_t) as sqlite3_int64); + sqlite3_bind_int64(select_stmt, 2i32, time() as sqlite3_int64); } else { select_stmt = dc_sqlite3_prepare( @@ -107,8 +107,8 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network: job.param, sqlite3_column_text(select_stmt, 3i32) as *mut libc::c_char, ); - job.added_timestamp = sqlite3_column_int64(select_stmt, 4i32) as time_t; - job.desired_timestamp = sqlite3_column_int64(select_stmt, 5i32) as time_t; + job.added_timestamp = sqlite3_column_int64(select_stmt, 4i32) as i64; + job.desired_timestamp = sqlite3_column_int64(select_stmt, 5i32) as i64; job.tries = sqlite3_column_int(select_stmt, 6i32); dc_log_info( context, @@ -204,7 +204,7 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network: let tries_0: libc::c_int = job.tries + 1i32; if tries_0 < 17i32 { job.tries = tries_0; - let time_offset: time_t = get_backoff_time_offset(tries_0); + let time_offset = get_backoff_time_offset(tries_0); job.desired_timestamp = job.added_timestamp + time_offset; dc_job_update(context, &mut job); dc_log_info(context, 0i32, @@ -219,7 +219,7 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network: }, job.job_id as libc::c_int, tries_0, time_offset, job.added_timestamp + time_offset - - time(0 as *mut time_t)); + time()); if thread == 5000i32 && tries_0 < 17i32 - 1i32 { context .smtp_state @@ -266,7 +266,7 @@ unsafe fn dc_job_delete(context: &Context, job: &dc_job_t) { /* ****************************************************************************** * Tools ******************************************************************************/ -unsafe fn get_backoff_time_offset(c_tries: libc::c_int) -> time_t { +unsafe fn get_backoff_time_offset(c_tries: libc::c_int) -> i64 { // results in ~3 weeks for the last backoff timespan let mut N = 2_i32.pow((c_tries - 1) as u32); N = N * 60; @@ -276,8 +276,9 @@ unsafe fn get_backoff_time_offset(c_tries: libc::c_int) -> time_t { if seconds < 1 { seconds = 1; } - seconds as time_t + seconds as i64 } + unsafe fn dc_job_update(context: &Context, job: &dc_job_t) { let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, @@ -537,10 +538,10 @@ unsafe fn dc_job_do_DC_JOB_MOVE_MSG(context: &Context, job: &mut dc_job_t) { /* ****************************************************************************** * IMAP-jobs ******************************************************************************/ -unsafe fn connect_to_inbox(context: &Context, inbox: &Imap) -> libc::c_int { +fn connect_to_inbox(context: &Context, inbox: &Imap) -> libc::c_int { let ret_connected: libc::c_int; - ret_connected = dc_connect_to_configured_imap(context, inbox); + ret_connected = unsafe { dc_connect_to_configured_imap(context, inbox) }; if !(0 == ret_connected) { inbox.set_watch_folder(b"INBOX\x00" as *const u8 as *const libc::c_char); } @@ -857,7 +858,7 @@ pub unsafe fn dc_job_add( param: *const libc::c_char, delay_seconds: libc::c_int, ) { - let timestamp: time_t = time(0 as *mut time_t); + let timestamp = time(); let stmt: *mut sqlite3_stmt; let thread: libc::c_int; if action >= 100i32 && action < 100i32 + 1000i32 { @@ -891,7 +892,7 @@ pub unsafe fn dc_job_add( sqlite3_bind_int64( stmt, 6i32, - (timestamp + delay_seconds as time_t) as sqlite3_int64, + (timestamp + delay_seconds as i64) as sqlite3_int64, ); sqlite3_step(stmt); sqlite3_finalize(stmt); @@ -1041,31 +1042,21 @@ pub unsafe fn dc_perform_imap_fetch(context: &Context) { ); } -pub unsafe fn dc_perform_imap_idle(context: &Context) { +pub fn dc_perform_imap_idle(context: &Context) { let inbox = context.inbox.read().unwrap(); connect_to_inbox(context, &inbox); if 0 != *context.perform_inbox_jobs_needed.clone().read().unwrap() { - dc_log_info( + info!( context, - 0i32, - b"INBOX-IDLE will not be started because of waiting jobs.\x00" as *const u8 - as *const libc::c_char, + 0, "INBOX-IDLE will not be started because of waiting jobs." ); return; } - dc_log_info( - context, - 0i32, - b"INBOX-IDLE started...\x00" as *const u8 as *const libc::c_char, - ); + info!(context, 0, "INBOX-IDLE started..."); inbox.idle(context); - dc_log_info( - context, - 0i32, - b"INBOX-IDLE ended.\x00" as *const u8 as *const libc::c_char, - ); + info!(context, 0, "INBOX-IDLE ended."); } pub unsafe fn dc_perform_mvbox_fetch(context: &Context) { @@ -1225,14 +1216,11 @@ unsafe fn get_next_wakeup_time(context: &Context, thread: libc::c_int) -> Durati let mut wakeup_time = Duration::new(10 * 60, 0); if sqlite3_step(stmt) == 100 { - let t = sqlite3_column_int(stmt, 0) as u64; - let now = SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap(); + let t = sqlite3_column_int(stmt, 0) as i64; + let now = time(); if t > 0 { - let t = Duration::new(t, 0); if t > now { - wakeup_time = t - now; + wakeup_time = Duration::new((t - now) as u64, 0); } else { wakeup_time = Duration::new(0, 0); } @@ -1380,18 +1368,10 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in ); } if 0 != mimefactory.out_gossiped { - dc_set_gossiped_timestamp( - context, - (*mimefactory.msg).chat_id, - time(0 as *mut time_t), - ); + dc_set_gossiped_timestamp(context, (*mimefactory.msg).chat_id, time()); } if 0 != mimefactory.out_last_added_location_id { - dc_set_kml_sent_timestamp( - context, - (*mimefactory.msg).chat_id, - time(0 as *mut time_t), - ); + dc_set_kml_sent_timestamp(context, (*mimefactory.msg).chat_id, time()); if 0 == (*mimefactory.msg).hidden { dc_set_msg_location_id( context, @@ -1409,7 +1389,7 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in dc_add_to_keyhistory( context, 0 as *const libc::c_char, - 0i32 as time_t, + 0, 0 as *const libc::c_char, 0 as *const libc::c_char, ); diff --git a/src/dc_jobthread.rs b/src/dc_jobthread.rs index 66be904bd..933ad38a8 100644 --- a/src/dc_jobthread.rs +++ b/src/dc_jobthread.rs @@ -124,7 +124,7 @@ pub unsafe fn dc_jobthread_fetch( state.using_handle = 1; } - if !0 == use_network { + if 0 != use_network { start = clock(); if !(0 == connect_to_imap(context, jobthread)) { dc_log_info( @@ -167,7 +167,7 @@ unsafe fn connect_to_imap(context: &Context, jobthread: &dc_jobthread_t) -> libc let mut mvbox_name: *mut libc::c_char = 0 as *mut libc::c_char; if jobthread.imap.is_connected() { - ret_connected = 1 + ret_connected = 1; } else { ret_connected = dc_connect_to_configured_imap(context, &jobthread.imap); if !(0 == ret_connected) { diff --git a/src/dc_location.rs b/src/dc_location.rs index 695b27dbc..ca797c528 100644 --- a/src/dc_location.rs +++ b/src/dc_location.rs @@ -22,7 +22,7 @@ pub struct dc_location_t { pub latitude: libc::c_double, pub longitude: libc::c_double, pub accuracy: libc::c_double, - pub timestamp: time_t, + pub timestamp: i64, pub contact_id: uint32_t, pub msg_id: uint32_t, pub chat_id: uint32_t, @@ -45,7 +45,7 @@ pub unsafe fn dc_send_locations_to_chat( seconds: libc::c_int, ) { let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; - let now: time_t = time(0 as *mut time_t); + let now = time(); let mut msg: *mut dc_msg_t = 0 as *mut dc_msg_t; let mut stock_str: *mut libc::c_char = 0 as *mut libc::c_char; let is_sending_locations_before: libc::c_int; @@ -66,7 +66,7 @@ pub unsafe fn dc_send_locations_to_chat( stmt, 2i32, (if 0 != seconds { - now + seconds as time_t + now + seconds as i64 } else { 0 }) as sqlite3_int64, @@ -145,7 +145,7 @@ pub unsafe fn dc_is_sending_locations_to_chat(context: &Context, chat_id: uint32 }, ); sqlite3_bind_int(stmt, 2i32, chat_id as libc::c_int); - sqlite3_bind_int64(stmt, 3i32, time(0 as *mut time_t) as sqlite3_int64); + sqlite3_bind_int64(stmt, 3i32, time() as sqlite3_int64); if !(sqlite3_step(stmt) != 100i32) { is_sending_locations = 1i32 } @@ -173,7 +173,7 @@ pub unsafe fn dc_set_location( b"SELECT id FROM chats WHERE locations_send_until>?;\x00" as *const u8 as *const libc::c_char, ); - sqlite3_bind_int64(stmt_chats, 1i32, time(0 as *mut time_t) as sqlite3_int64); + sqlite3_bind_int64(stmt_chats, 1i32, time() as sqlite3_int64); while sqlite3_step(stmt_chats) == 100i32 { let chat_id: uint32_t = sqlite3_column_int(stmt_chats, 0i32) as uint32_t; stmt_insert = @@ -185,7 +185,7 @@ pub unsafe fn dc_set_location( sqlite3_bind_double(stmt_insert, 1i32, latitude); sqlite3_bind_double(stmt_insert, 2i32, longitude); sqlite3_bind_double(stmt_insert, 3i32, accuracy); - sqlite3_bind_int64(stmt_insert, 4i32, time(0 as *mut time_t) as sqlite3_int64); + sqlite3_bind_int64(stmt_insert, 4i32, time() as sqlite3_int64); sqlite3_bind_int(stmt_insert, 5i32, chat_id as libc::c_int); sqlite3_bind_int(stmt_insert, 6i32, 1i32); sqlite3_step(stmt_insert); @@ -211,14 +211,14 @@ pub unsafe fn dc_get_locations( context: &Context, chat_id: uint32_t, contact_id: uint32_t, - timestamp_from: time_t, - mut timestamp_to: time_t, + timestamp_from: i64, + mut timestamp_to: i64, ) -> *mut dc_array_t { let ret: *mut dc_array_t = dc_array_new_typed(1i32, 500i32 as size_t); let stmt: *mut sqlite3_stmt; if timestamp_to == 0 { - timestamp_to = time(0 as *mut time_t) + 10; + timestamp_to = time() + 10; } stmt = dc_sqlite3_prepare( context, @@ -263,7 +263,7 @@ pub unsafe fn dc_get_locations( (*loc).latitude = sqlite3_column_double(stmt, 1i32); (*loc).longitude = sqlite3_column_double(stmt, 2i32); (*loc).accuracy = sqlite3_column_double(stmt, 3i32); - (*loc).timestamp = sqlite3_column_int64(stmt, 4i32) as time_t; + (*loc).timestamp = sqlite3_column_int64(stmt, 4i32) as i64; (*loc).independent = sqlite3_column_int(stmt, 5i32) as uint32_t; (*loc).msg_id = sqlite3_column_int(stmt, 6i32) as uint32_t; (*loc).contact_id = sqlite3_column_int(stmt, 7i32) as uint32_t; @@ -322,10 +322,10 @@ pub unsafe fn dc_get_location_kml( let mut success: libc::c_int = 0i32; let mut stmt: *mut sqlite3_stmt; let self_addr: *mut libc::c_char; - let now: time_t = time(0 as *mut time_t); - let locations_send_begin: time_t; - let locations_send_until: time_t; - let locations_last_sent: time_t; + let now = time(); + let locations_send_begin: i64; + let locations_send_until: i64; + let locations_last_sent: i64; let mut location_count: libc::c_int = 0i32; let mut ret: dc_strbuilder_t = dc_strbuilder_t { buf: 0 as *mut libc::c_char, @@ -349,9 +349,9 @@ pub unsafe fn dc_get_location_kml( as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); if !(sqlite3_step(stmt) != 100i32) { - locations_send_begin = sqlite3_column_int64(stmt, 0i32) as time_t; - locations_send_until = sqlite3_column_int64(stmt, 1i32) as time_t; - locations_last_sent = sqlite3_column_int64(stmt, 2i32) as time_t; + locations_send_begin = sqlite3_column_int64(stmt, 0i32) as i64; + locations_send_until = sqlite3_column_int64(stmt, 1i32) as i64; + locations_last_sent = sqlite3_column_int64(stmt, 2i32) as i64; sqlite3_finalize(stmt); stmt = 0 as *mut sqlite3_stmt; if !(locations_send_begin == 0 || now > locations_send_until) { @@ -382,7 +382,7 @@ pub unsafe fn dc_get_location_kml( let longitude: *mut libc::c_char = dc_ftoa(sqlite3_column_double(stmt, 2i32)); let accuracy: *mut libc::c_char = dc_ftoa(sqlite3_column_double(stmt, 3i32)); let timestamp: *mut libc::c_char = - get_kml_timestamp(sqlite3_column_int64(stmt, 4i32) as time_t); + get_kml_timestamp(sqlite3_column_int64(stmt, 4i32) as i64); dc_strbuilder_catf(&mut ret as *mut dc_strbuilder_t, b"%s%s,%s\n\x00" as *const u8 as @@ -422,40 +422,16 @@ pub unsafe fn dc_get_location_kml( /******************************************************************************* * create kml-files ******************************************************************************/ -unsafe fn get_kml_timestamp(mut utc: time_t) -> *mut libc::c_char { +unsafe fn get_kml_timestamp(utc: i64) -> *mut libc::c_char { // Returns a string formatted as YYYY-MM-DDTHH:MM:SSZ. The trailing `Z` indicates UTC. - let mut wanted_struct: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *mut libc::c_char, - }; - memcpy( - &mut wanted_struct as *mut tm as *mut libc::c_void, - gmtime(&mut utc) as *const libc::c_void, - ::std::mem::size_of::(), - ); - - dc_mprintf( - b"%04i-%02i-%02iT%02i:%02i:%02iZ\x00" as *const u8 as *const libc::c_char, - wanted_struct.tm_year as libc::c_int + 1900i32, - wanted_struct.tm_mon as libc::c_int + 1i32, - wanted_struct.tm_mday as libc::c_int, - wanted_struct.tm_hour as libc::c_int, - wanted_struct.tm_min as libc::c_int, - wanted_struct.tm_sec as libc::c_int, - ) + let res = chrono::NaiveDateTime::from_timestamp(utc, 0) + .format("%Y-%m-%dT%H:%M:%SZ") + .to_string(); + strdup(to_cstring(res).as_ptr()) } pub unsafe fn dc_get_message_kml( - timestamp: time_t, + timestamp: i64, latitude: libc::c_double, longitude: libc::c_double, ) -> *mut libc::c_char { @@ -485,9 +461,8 @@ pub unsafe fn dc_get_message_kml( ret } -pub unsafe fn dc_set_kml_sent_timestamp(context: &Context, chat_id: uint32_t, timestamp: time_t) { - let stmt: *mut sqlite3_stmt; - stmt = dc_sqlite3_prepare( +pub unsafe fn dc_set_kml_sent_timestamp(context: &Context, chat_id: uint32_t, timestamp: i64) { + let stmt = dc_sqlite3_prepare( context, &context.sql.clone().read().unwrap(), b"UPDATE chats SET locations_last_sent=? WHERE id=?;\x00" as *const u8 @@ -521,7 +496,7 @@ pub unsafe fn dc_save_locations( ) -> uint32_t { let mut stmt_test: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; let mut stmt_insert: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; - let mut newest_timestamp: time_t = 0i32 as time_t; + let mut newest_timestamp = 0; let mut newest_location_id: uint32_t = 0i32 as uint32_t; if !(chat_id <= 9i32 as libc::c_uint || locations.is_null()) { stmt_test = dc_sqlite3_prepare( @@ -643,39 +618,19 @@ unsafe fn kml_text_cb(userdata: *mut libc::c_void, text: *const libc::c_char, _l b"\x00" as *const u8 as *const libc::c_char, ); if 0 != (*kml).tag & 0x4 && strlen(val) >= 19 { - let mut tmval: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *mut libc::c_char, - }; - memset( - &mut tmval as *mut tm as *mut libc::c_void, - 0, - ::std::mem::size_of::(), - ); - *val.offset(4isize) = 0i32 as libc::c_char; - tmval.tm_year = atoi(val) - 1900i32; - *val.offset(7isize) = 0i32 as libc::c_char; - tmval.tm_mon = atoi(val.offset(5isize)) - 1i32; - *val.offset(10isize) = 0i32 as libc::c_char; - tmval.tm_mday = atoi(val.offset(8isize)); - *val.offset(13isize) = 0i32 as libc::c_char; - tmval.tm_hour = atoi(val.offset(11isize)); - *val.offset(16isize) = 0i32 as libc::c_char; - tmval.tm_min = atoi(val.offset(14isize)); - *val.offset(19isize) = 0i32 as libc::c_char; - tmval.tm_sec = atoi(val.offset(17isize)); - (*kml).curr.timestamp = mkgmtime(&mut tmval); - if (*kml).curr.timestamp > time(0 as *mut time_t) { - (*kml).curr.timestamp = time(0 as *mut time_t) + // YYYY-MM-DDTHH:MM:SSZ + // 0 4 7 10 13 16 19 + let val_r = to_str(val); + match chrono::NaiveDateTime::parse_from_str(val_r, "%Y-%m-%dT%H:%M:%SZ") { + Ok(res) => { + (*kml).curr.timestamp = res.timestamp(); + if (*kml).curr.timestamp > time() { + (*kml).curr.timestamp = time(); + } + } + Err(_err) => { + (*kml).curr.timestamp = time(); + } } } else if 0 != (*kml).tag & 0x10i32 { let mut comma: *mut libc::c_char = strchr(val, ',' as i32); @@ -729,7 +684,7 @@ unsafe fn kml_starttag_cb( } } else if strcmp(tag, b"placemark\x00" as *const u8 as *const libc::c_char) == 0i32 { (*kml).tag = 0x1i32; - (*kml).curr.timestamp = 0i32 as time_t; + (*kml).curr.timestamp = 0; (*kml).curr.latitude = 0i32 as libc::c_double; (*kml).curr.longitude = 0.0f64; (*kml).curr.accuracy = 0.0f64 @@ -769,7 +724,7 @@ pub unsafe fn dc_kml_unref(kml: *mut dc_kml_t) { pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mut dc_job_t) { let stmt_chats: *mut sqlite3_stmt; let mut stmt_locations: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; - let now: time_t = time(0 as *mut time_t); + let now = time(); let mut continue_streaming: libc::c_int = 1i32; dc_log_info( context, @@ -787,8 +742,8 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu sqlite3_bind_int64(stmt_chats, 1i32, now as sqlite3_int64); while sqlite3_step(stmt_chats) == 100i32 { let chat_id: uint32_t = sqlite3_column_int(stmt_chats, 0i32) as uint32_t; - let locations_send_begin: time_t = sqlite3_column_int64(stmt_chats, 1i32) as time_t; - let locations_last_sent: time_t = sqlite3_column_int64(stmt_chats, 2i32) as time_t; + let locations_send_begin = sqlite3_column_int64(stmt_chats, 1i32) as i64; + let locations_last_sent = sqlite3_column_int64(stmt_chats, 2i32) as i64; continue_streaming = 1i32; // be a bit tolerant as the timer may not align exactly with time(NULL) if now - locations_last_sent < (60 - 3) { @@ -844,8 +799,8 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOC_ENDED(context: &Context, job: &mut // the function checks, if location-streaming is really ended; // if so, a device-message is added if not yet done. let chat_id: uint32_t = (*job).foreign_id; - let locations_send_begin: time_t; - let locations_send_until: time_t; + let locations_send_begin: i64; + let locations_send_until: i64; let mut stmt; let mut stock_str: *mut libc::c_char = 0 as *mut libc::c_char; stmt = dc_sqlite3_prepare( @@ -856,11 +811,11 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOC_ENDED(context: &Context, job: &mut ); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); if !(sqlite3_step(stmt) != 100i32) { - locations_send_begin = sqlite3_column_int64(stmt, 0i32) as time_t; - locations_send_until = sqlite3_column_int64(stmt, 1i32) as time_t; + locations_send_begin = sqlite3_column_int64(stmt, 0i32) as i64; + locations_send_until = sqlite3_column_int64(stmt, 1i32) as i64; sqlite3_finalize(stmt); stmt = 0 as *mut sqlite3_stmt; - if !(locations_send_begin != 0 && time(0 as *mut time_t) <= locations_send_until) { + if !(locations_send_begin != 0 && time() <= locations_send_until) { // still streaming - // may happen as several calls to dc_send_locations_to_chat() // do not un-schedule pending DC_MAYBE_SEND_LOC_ENDED jobs diff --git a/src/dc_log.rs b/src/dc_log.rs index 9fbd3b087..2ab281aa7 100644 --- a/src/dc_log.rs +++ b/src/dc_log.rs @@ -139,3 +139,21 @@ macro_rules! error { } }; } + +#[macro_export] +macro_rules! log_event { + ($ctx:expr, $data1:expr, $msg:expr) => { + log_event!($ctx, $data1, $msg,) + }; + ($ctx:expr, $event:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { + unsafe { + dc_log_event( + $ctx, + $event, + $data1, + std::ffi::CString::new($msg).unwrap().as_ptr(), + $($args),* + ) + } + }; +} diff --git a/src/dc_lot.rs b/src/dc_lot.rs index 075cee01f..c913258e1 100644 --- a/src/dc_lot.rs +++ b/src/dc_lot.rs @@ -15,7 +15,7 @@ pub struct dc_lot_t { pub text1_meaning: libc::c_int, pub text1: *mut libc::c_char, pub text2: *mut libc::c_char, - pub timestamp: time_t, + pub timestamp: i64, pub state: libc::c_int, pub id: uint32_t, pub fingerprint: *mut libc::c_char, @@ -60,7 +60,7 @@ pub unsafe fn dc_lot_empty(mut lot: *mut dc_lot_t) { (*lot).invitenumber = 0 as *mut libc::c_char; free((*lot).auth as *mut libc::c_void); (*lot).auth = 0 as *mut libc::c_char; - (*lot).timestamp = 0i32 as time_t; + (*lot).timestamp = 0; (*lot).state = 0i32; (*lot).id = 0i32 as uint32_t; } @@ -114,9 +114,9 @@ pub unsafe fn dc_lot_get_id(lot: *const dc_lot_t) -> uint32_t { (*lot).id } -pub unsafe fn dc_lot_get_timestamp(lot: *const dc_lot_t) -> time_t { +pub unsafe fn dc_lot_get_timestamp(lot: *const dc_lot_t) -> i64 { if lot.is_null() || (*lot).magic != 0x107107i32 as libc::c_uint { - return 0i32 as time_t; + return 0; } (*lot).timestamp diff --git a/src/dc_mimefactory.rs b/src/dc_mimefactory.rs index 849db340c..903e0195b 100644 --- a/src/dc_mimefactory.rs +++ b/src/dc_mimefactory.rs @@ -1,3 +1,4 @@ +use chrono::TimeZone; use mmime::mailimf_types::*; use mmime::mailimf_types_helper::*; use mmime::mailmime_disposition::*; @@ -31,7 +32,7 @@ pub struct dc_mimefactory_t<'a> { pub selfstatus: *mut libc::c_char, pub recipients_names: *mut clist, pub recipients_addr: *mut clist, - pub timestamp: time_t, + pub timestamp: i64, pub rfc724_mid: *mut libc::c_char, pub loaded: dc_mimefactory_loaded_t, pub msg: *mut dc_msg_t<'a>, @@ -103,7 +104,7 @@ pub unsafe fn dc_mimefactory_empty(mut factory: *mut dc_mimefactory_t) { (*factory).loaded = DC_MF_NOTHING_LOADED; free((*factory).error as *mut libc::c_void); (*factory).error = 0 as *mut libc::c_char; - (*factory).timestamp = 0i32 as time_t; + (*factory).timestamp = 0; } pub unsafe fn dc_mimefactory_load_msg( @@ -445,7 +446,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: ) } imf_fields = mailimf_fields_new_with_data_all( - mailimf_get_date((*factory).timestamp), + mailimf_get_date((*factory).timestamp as i64), from, 0 as *mut mailimf_mailbox, 0 as *mut mailimf_address_list, @@ -522,7 +523,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: } } if (*chat).gossiped_timestamp == 0 - || ((*chat).gossiped_timestamp + (2 * 24 * 60 * 60)) < time(0 as *mut time_t) + || ((*chat).gossiped_timestamp + (2 * 24 * 60 * 60)) < time() { do_gossip = 1i32 } @@ -1135,39 +1136,20 @@ unsafe fn build_body_file( let mut filename_encoded: *mut libc::c_char = 0 as *mut libc::c_char; if !pathNfilename.is_null() { if (*msg).type_0 == 41i32 { - let mut wanted_struct: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *mut libc::c_char, + let ts = chrono::Utc.timestamp((*msg).timestamp_sort as i64, 0); + + let suffix = if !suffix.is_null() { + to_string(suffix) + } else { + "dat".into() }; - memcpy( - &mut wanted_struct as *mut tm as *mut libc::c_void, - localtime(&(*msg).timestamp_sort) as *const libc::c_void, - ::std::mem::size_of::(), - ); - filename_to_send = dc_mprintf( - b"voice-message_%04i-%02i-%02i_%02i-%02i-%02i.%s\x00" as *const u8 - as *const libc::c_char, - wanted_struct.tm_year as libc::c_int + 1900i32, - wanted_struct.tm_mon as libc::c_int + 1i32, - wanted_struct.tm_mday as libc::c_int, - wanted_struct.tm_hour as libc::c_int, - wanted_struct.tm_min as libc::c_int, - wanted_struct.tm_sec as libc::c_int, - if !suffix.is_null() { + let res = ts + .format(&format!( + "voice-message_%04i-%02i-%02i_%02i-%02i-%02i.{}", suffix - } else { - b"dat\x00" as *const u8 as *const libc::c_char - }, - ) + )) + .to_string(); + filename_to_send = strdup(to_cstring(res).as_ptr()); } else if (*msg).type_0 == 40i32 { filename_to_send = dc_get_filename(pathNfilename) } else if (*msg).type_0 == 20i32 || (*msg).type_0 == 21i32 { diff --git a/src/dc_msg.rs b/src/dc_msg.rs index e05bc1dfb..da0a071cf 100644 --- a/src/dc_msg.rs +++ b/src/dc_msg.rs @@ -28,9 +28,9 @@ pub struct dc_msg_t<'a> { pub type_0: libc::c_int, pub state: libc::c_int, pub hidden: libc::c_int, - pub timestamp_sort: time_t, - pub timestamp_sent: time_t, - pub timestamp_rcvd: time_t, + pub timestamp_sort: i64, + pub timestamp_sent: i64, + pub timestamp_rcvd: i64, pub text: *mut libc::c_char, pub context: &'a Context, pub rfc724_mid: *mut libc::c_char, @@ -125,7 +125,7 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: uint32_t) -> *mut libc: sqlite3_bind_int(stmt, 1i32, msg_id as libc::c_int); while sqlite3_step(stmt) == 100i32 { dc_strbuilder_cat(&mut ret, b"Read: \x00" as *const u8 as *const libc::c_char); - p = dc_timestamp_to_str(sqlite3_column_int64(stmt, 1i32) as time_t); + p = dc_timestamp_to_str(sqlite3_column_int64(stmt, 1i32) as i64); dc_strbuilder_cat(&mut ret, p); free(p as *mut libc::c_void); dc_strbuilder_cat(&mut ret, b" by \x00" as *const u8 as *const libc::c_char); @@ -490,9 +490,9 @@ pub unsafe fn dc_msg_set_location( ); } -pub unsafe fn dc_msg_get_timestamp(msg: *const dc_msg_t) -> time_t { +pub unsafe fn dc_msg_get_timestamp(msg: *const dc_msg_t) -> i64 { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { - return 0i32 as time_t; + return 0; } return if 0 != (*msg).timestamp_sent { (*msg).timestamp_sent @@ -565,13 +565,13 @@ unsafe fn dc_msg_set_from_stmt( (*msg).to_id = sqlite3_column_int(row, fresh8) as uint32_t; let fresh9 = row_offset; row_offset = row_offset + 1; - (*msg).timestamp_sort = sqlite3_column_int64(row, fresh9) as time_t; + (*msg).timestamp_sort = sqlite3_column_int64(row, fresh9) as i64; let fresh10 = row_offset; row_offset = row_offset + 1; - (*msg).timestamp_sent = sqlite3_column_int64(row, fresh10) as time_t; + (*msg).timestamp_sent = sqlite3_column_int64(row, fresh10) as i64; let fresh11 = row_offset; row_offset = row_offset + 1; - (*msg).timestamp_rcvd = sqlite3_column_int64(row, fresh11) as time_t; + (*msg).timestamp_rcvd = sqlite3_column_int64(row, fresh11) as i64; let fresh12 = row_offset; row_offset = row_offset + 1; (*msg).type_0 = sqlite3_column_int(row, fresh12); @@ -818,17 +818,17 @@ pub unsafe fn dc_msg_get_state(msg: *const dc_msg_t) -> libc::c_int { (*msg).state } -pub unsafe fn dc_msg_get_received_timestamp(msg: *const dc_msg_t) -> time_t { +pub unsafe fn dc_msg_get_received_timestamp(msg: *const dc_msg_t) -> i64 { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { - return 0i32 as time_t; + return 0; } (*msg).timestamp_rcvd } -pub unsafe fn dc_msg_get_sort_timestamp(msg: *const dc_msg_t) -> time_t { +pub unsafe fn dc_msg_get_sort_timestamp(msg: *const dc_msg_t) -> i64 { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { - return 0i32 as time_t; + return 0; } (*msg).timestamp_sort @@ -1051,8 +1051,8 @@ pub unsafe fn dc_msg_get_summarytext_by_raw( pub unsafe fn dc_msg_has_deviating_timestamp(msg: *const dc_msg_t) -> libc::c_int { let cnv_to_local = dc_gm2local_offset(); - let sort_timestamp: time_t = dc_msg_get_sort_timestamp(msg) + cnv_to_local; - let send_timestamp: time_t = dc_msg_get_timestamp(msg) + cnv_to_local; + let sort_timestamp = dc_msg_get_sort_timestamp(msg) as i64 + cnv_to_local; + let send_timestamp = dc_msg_get_timestamp(msg) as i64 + cnv_to_local; (sort_timestamp / 86400 != send_timestamp / 86400) as libc::c_int } @@ -1372,7 +1372,7 @@ pub unsafe fn dc_mdn_from_ext( context: &Context, from_id: uint32_t, rfc724_mid: *const libc::c_char, - timestamp_sent: time_t, + timestamp_sent: i64, ret_chat_id: *mut uint32_t, ret_msg_id: *mut uint32_t, ) -> libc::c_int { diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index fb0150b4c..24fefd7c3 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -58,9 +58,9 @@ pub unsafe fn dc_receive_imf( let mut icnt: size_t; /* Message-ID from the header */ let mut rfc724_mid: *mut libc::c_char = 0 as *mut libc::c_char; - let mut sort_timestamp: time_t = -1i32 as time_t; - let mut sent_timestamp: time_t = -1i32 as time_t; - let mut rcvd_timestamp: time_t = -1i32 as time_t; + let mut sort_timestamp = 0; + let mut sent_timestamp = 0; + let mut rcvd_timestamp = 0; let mut mime_parser = dc_mimeparser_new(context); let mut field: *const mailimf_field; let mut mime_in_reply_to: *mut libc::c_char = 0 as *mut libc::c_char; @@ -686,8 +686,8 @@ pub unsafe fn dc_receive_imf( } } } else { - if sent_timestamp > time(0 as *mut time_t) { - sent_timestamp = time(0 as *mut time_t) + if sent_timestamp > time() { + sent_timestamp = time() } current_block = 18330534242458572360; } @@ -1017,13 +1017,13 @@ unsafe fn calc_timestamps( context: &Context, chat_id: uint32_t, from_id: uint32_t, - message_timestamp: time_t, + message_timestamp: i64, is_fresh_msg: libc::c_int, - sort_timestamp: *mut time_t, - sent_timestamp: *mut time_t, - rcvd_timestamp: *mut time_t, + sort_timestamp: *mut i64, + sent_timestamp: *mut i64, + rcvd_timestamp: *mut i64, ) { - *rcvd_timestamp = time(0 as *mut time_t); + *rcvd_timestamp = time(); *sent_timestamp = message_timestamp; if *sent_timestamp > *rcvd_timestamp { *sent_timestamp = *rcvd_timestamp @@ -1040,7 +1040,7 @@ unsafe fn calc_timestamps( sqlite3_bind_int(stmt, 2i32, from_id as libc::c_int); sqlite3_bind_int64(stmt, 3i32, *sort_timestamp as sqlite3_int64); if sqlite3_step(stmt) == 100i32 { - let last_msg_time: time_t = sqlite3_column_int64(stmt, 0i32) as time_t; + let last_msg_time = sqlite3_column_int64(stmt, 0i32) as i64; if last_msg_time > 0 { if *sort_timestamp <= last_msg_time { *sort_timestamp = last_msg_time + 1 diff --git a/src/dc_sqlite3.rs b/src/dc_sqlite3.rs index 25eaf7bae..26208ec3f 100644 --- a/src/dc_sqlite3.rs +++ b/src/dc_sqlite3.rs @@ -1289,7 +1289,7 @@ pub unsafe fn dc_sqlite3_set_config_int64( ) -> libc::c_int { let value_str = dc_mprintf( b"%lld\x00" as *const u8 as *const libc::c_char, - value as time_t, + value as i64, ); if value_str.is_null() { return 0; diff --git a/src/dc_token.rs b/src/dc_token.rs index bc33fe529..9a4682204 100644 --- a/src/dc_token.rs +++ b/src/dc_token.rs @@ -2,7 +2,6 @@ use crate::context::Context; use crate::dc_sqlite3::*; use crate::dc_tools::*; use crate::types::*; -use crate::x::*; // Token namespaces pub type dc_tokennamespc_t = libc::c_uint; @@ -27,7 +26,7 @@ pub unsafe fn dc_token_save( sqlite3_bind_int(stmt, 1i32, namespc as libc::c_int); sqlite3_bind_int(stmt, 2i32, foreign_id as libc::c_int); sqlite3_bind_text(stmt, 3i32, token, -1i32, None); - sqlite3_bind_int64(stmt, 4i32, time(0 as *mut time_t) as sqlite3_int64); + sqlite3_bind_int64(stmt, 4i32, time() as sqlite3_int64); sqlite3_step(stmt); } sqlite3_finalize(stmt); diff --git a/src/dc_tools.rs b/src/dc_tools.rs index bb7bf204a..fa268dc2e 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -1,5 +1,7 @@ use std::fs; +use std::time::SystemTime; +use chrono::{Local, TimeZone}; use mmime::mailimf_types::*; use rand::{thread_rng, Rng}; @@ -682,194 +684,52 @@ pub unsafe fn clist_search_string_nocase( /* date/time tools */ /* the result is UTC or DC_INVALID_TIMESTAMP */ -pub unsafe fn dc_timestamp_from_date(date_time: *mut mailimf_date_time) -> time_t { - let mut tmval: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *mut libc::c_char, - }; - let mut timeval: time_t; - let zone_min: libc::c_int; - let zone_hour: libc::c_int; - memset( - &mut tmval as *mut tm as *mut libc::c_void, - 0, - ::std::mem::size_of::(), +pub unsafe fn dc_timestamp_from_date(date_time: *mut mailimf_date_time) -> i64 { + let sec = (*date_time).dt_sec; + let min = (*date_time).dt_min; + let hour = (*date_time).dt_hour; + let day = (*date_time).dt_day; + let month = (*date_time).dt_month; + let year = (*date_time).dt_year; + + let ts = chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd(year, month as u32, day as u32), + chrono::NaiveTime::from_hms(hour as u32, min as u32, sec as u32), ); - tmval.tm_sec = (*date_time).dt_sec; - tmval.tm_min = (*date_time).dt_min; - tmval.tm_hour = (*date_time).dt_hour; - tmval.tm_mday = (*date_time).dt_day; - tmval.tm_mon = (*date_time).dt_month - 1i32; - if (*date_time).dt_year < 1000i32 { - tmval.tm_year = (*date_time).dt_year + 2000i32 - 1900i32 - } else { - tmval.tm_year = (*date_time).dt_year - 1900i32 - } - timeval = mkgmtime(&mut tmval); - if (*date_time).dt_zone >= 0i32 { - zone_hour = (*date_time).dt_zone / 100i32; - zone_min = (*date_time).dt_zone % 100i32 - } else { - zone_hour = -(-(*date_time).dt_zone / 100i32); - zone_min = -(-(*date_time).dt_zone % 100i32) - } - timeval -= (zone_hour * 3600 + zone_min * 60) as time_t; - timeval -} - -pub unsafe fn mkgmtime(tmp: *mut tm) -> time_t { - let mut dir: libc::c_int; - let mut bits: libc::c_int; - let saved_seconds: libc::c_int; - let mut t: time_t; - let mut yourtm: tm; - let mut mytm: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *mut libc::c_char, + let (zone_hour, zone_min) = if (*date_time).dt_zone >= 0 { + ((*date_time).dt_zone / 100i32, (*date_time).dt_zone % 100i32) + } else { + ( + -(-(*date_time).dt_zone / 100i32), + -(-(*date_time).dt_zone % 100i32), + ) }; - yourtm = *tmp; - saved_seconds = yourtm.tm_sec; - yourtm.tm_sec = 0i32; - bits = 0i32; - t = 1i32 as time_t; - while t > 0 { - bits += 1; - t <<= 1i32 - } - if bits > 40i32 { - bits = 40i32 - } - t = if t < 0 { 0 } else { (1i32 as time_t) << bits }; - loop { - gmtime_r(&mut t, &mut mytm); - dir = tmcomp(&mut mytm, &mut yourtm); - if !(dir != 0i32) { - break; - } - let fresh2 = bits; - bits = bits - 1; - if fresh2 < 0i32 { - return -1i32 as time_t; - } - if bits < 0i32 { - t -= 1 - } else if dir > 0i32 { - t -= (1i32 as time_t) << bits - } else { - t += (1i32 as time_t) << bits - } - } - t += saved_seconds as time_t; - t + ts.timestamp() - (zone_hour * 3600 + zone_min * 60) as i64 } /* ****************************************************************************** * date/time tools ******************************************************************************/ -unsafe fn tmcomp(atmp: *mut tm, btmp: *mut tm) -> libc::c_int { - let mut result: libc::c_int; - result = (*atmp).tm_year - (*btmp).tm_year; - if result == 0i32 - && { - result = (*atmp).tm_mon - (*btmp).tm_mon; - result == 0i32 - } - && { - result = (*atmp).tm_mday - (*btmp).tm_mday; - result == 0i32 - } - && { - result = (*atmp).tm_hour - (*btmp).tm_hour; - result == 0i32 - } - && { - result = (*atmp).tm_min - (*btmp).tm_min; - result == 0i32 - } - { - result = (*atmp).tm_sec - (*btmp).tm_sec - } - - result -} /* the return value must be free()'d */ -pub unsafe fn dc_timestamp_to_str(mut wanted: time_t) -> *mut libc::c_char { - let mut wanted_struct: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *mut libc::c_char, - }; - memcpy( - &mut wanted_struct as *mut tm as *mut libc::c_void, - localtime(&mut wanted) as *const libc::c_void, - ::std::mem::size_of::(), - ); - return dc_mprintf( - b"%02i.%02i.%04i %02i:%02i:%02i\x00" as *const u8 as *const libc::c_char, - wanted_struct.tm_mday as libc::c_int, - wanted_struct.tm_mon as libc::c_int + 1i32, - wanted_struct.tm_year as libc::c_int + 1900i32, - wanted_struct.tm_hour as libc::c_int, - wanted_struct.tm_min as libc::c_int, - wanted_struct.tm_sec as libc::c_int, - ); +pub unsafe fn dc_timestamp_to_str(wanted: i64) -> *mut libc::c_char { + let ts = chrono::Utc.timestamp(wanted, 0); + let res = ts.format("%Y.%m.%d %H:%M:%S").to_string(); + + strdup(to_cstring(res).as_ptr()) } -pub unsafe fn dc_gm2local_offset() -> time_t { - /* returns the offset that must be _added_ to an UTC/GMT-time to create the localtime. - the function may return nagative values. */ - let mut gmtime: time_t = time(0 as *mut time_t); - let mut timeinfo: tm = tm { - tm_sec: 0i32, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *mut libc::c_char, - }; - localtime_r(&mut gmtime, &mut timeinfo); - - timeinfo.tm_gmtoff +pub fn dc_gm2local_offset() -> i64 { + let lt = Local::now(); + ((lt.offset().local_minus_utc() / (60 * 60)) * 100) as i64 } /* timesmearing */ -pub unsafe fn dc_smeared_time(context: &Context) -> time_t { +pub unsafe fn dc_smeared_time(context: &Context) -> i64 { /* function returns a corrected time(NULL) */ - let mut now: time_t = time(0 as *mut time_t); + let mut now = time(); let ts = *context.last_smeared_timestamp.clone().read().unwrap(); if ts >= now { now = ts + 1; @@ -878,9 +738,9 @@ pub unsafe fn dc_smeared_time(context: &Context) -> time_t { now } -pub unsafe fn dc_create_smeared_timestamp(context: &Context) -> time_t { - let now: time_t = time(0 as *mut time_t); - let mut ret: time_t = now; +pub unsafe fn dc_create_smeared_timestamp(context: &Context) -> i64 { + let now = time(); + let mut ret = now; let ts = *context.last_smeared_timestamp.clone().write().unwrap(); if ret <= ts { @@ -893,10 +753,10 @@ pub unsafe fn dc_create_smeared_timestamp(context: &Context) -> time_t { ret } -pub unsafe fn dc_create_smeared_timestamps(context: &Context, count: libc::c_int) -> time_t { +pub unsafe fn dc_create_smeared_timestamps(context: &Context, count: libc::c_int) -> i64 { /* get a range to timestamps that can be used uniquely */ - let now = time(0 as *mut time_t); - let start = now + (if count < 5 { count } else { 5 }) as time_t - count as time_t; + let now = time(); + let start = now + (if count < 5 { count } else { 5 }) as i64 - count as i64; let ts = *context.last_smeared_timestamp.clone().write().unwrap(); if ts + 1 > start { @@ -962,7 +822,7 @@ unsafe fn encode_66bits_as_base64(v1: uint32_t, v2: uint32_t, fill: uint32_t) -> } pub unsafe fn dc_create_incoming_rfc724_mid( - message_timestamp: time_t, + message_timestamp: i64, contact_id_from: uint32_t, contact_ids_to: *mut dc_array_t, ) -> *mut libc::c_char { @@ -1529,7 +1389,7 @@ pub unsafe fn dc_get_fine_pathNfilename( let filenameNsuffix: *mut libc::c_char; let mut basename: *mut libc::c_char = 0 as *mut libc::c_char; let mut dotNSuffix: *mut libc::c_char = 0 as *mut libc::c_char; - let now: time_t = time(0 as *mut time_t); + let now = time(); let mut i: libc::c_int = 0i32; pathNfolder_wo_slash = dc_strdup(pathNfolder); dc_ensure_no_slash(pathNfolder_wo_slash); @@ -1539,11 +1399,7 @@ pub unsafe fn dc_get_fine_pathNfilename( while i < 1000i32 { /*no deadlocks, please*/ if 0 != i { - let idx = if i < 100 { - i as time_t - } else { - now + i as time_t - }; + let idx = if i < 100 { i as i64 } else { now + i as i64 }; ret = dc_mprintf( b"%s/%s-%lu%s\x00" as *const u8 as *const libc::c_char, pathNfolder_wo_slash, @@ -1652,6 +1508,13 @@ pub fn to_str<'a>(s: *const libc::c_char) -> &'a str { unsafe { std::ffi::CStr::from_ptr(s).to_str().unwrap() } } +pub fn time() -> i64 { + SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs() as i64 +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/imap.rs b/src/imap.rs index e39d32f87..9f18d52b9 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -372,6 +372,10 @@ impl Imap { } fn setup_handle_if_needed(&self, context: &Context) -> libc::c_int { + if self.config.read().unwrap().imap_server.is_empty() { + return 0; + } + if self.should_reconnect() { self.unsetup_handle(context); } @@ -433,18 +437,15 @@ impl Imap { let imap_server: &str = config.imap_server.as_ref(); let imap_port = config.imap_port; - eprintln!("failed to connect: {:?}", err); - unsafe { - dc_log_event_seq( - context, - Event::ERROR_NETWORK, - &mut 0 as *mut i32, - b"Could not connect to IMAP-server %s:%i.\x00" as *const u8 - as *const libc::c_char, - imap_server, - imap_port as usize as libc::c_int, - ) - }; + log_event!( + context, + Event::ERROR_NETWORK, + 0, + format!( + "Could not connect to IMAP-server {}:{}. ({})", + imap_server, imap_port, err + ), + ); return 0; } @@ -458,15 +459,12 @@ impl Imap { 1 } Err((err, _)) => { - eprintln!("failed to login: {:?}", err); - unsafe { - dc_log_event_seq( - context, - Event::ERROR_NETWORK, - &mut 0 as *mut i32, - b"Cannot login\x00" as *const u8 as *const libc::c_char, - ) - }; + log_event!( + context, + Event::ERROR_NETWORK, + 0, + format!("Cannot login ({})", err), + ); self.unsetup_handle(context); @@ -547,6 +545,7 @@ impl Imap { } if self.setup_handle_if_needed(context) == 0 { + self.free_connect_params(); return 0; } diff --git a/src/key.rs b/src/key.rs index ddd64f9ed..87b2a334e 100644 --- a/src/key.rs +++ b/src/key.rs @@ -377,7 +377,7 @@ pub fn dc_key_save_self_keypair( None, ) }; - unsafe { sqlite3_bind_int64(stmt, 5, libc::time(0 as *mut time_t) as sqlite3_int64) }; + unsafe { sqlite3_bind_int64(stmt, 5, time() as sqlite3_int64) }; let success = if unsafe { sqlite3_step(stmt) } == 101 { true } else { diff --git a/src/keyhistory.rs b/src/keyhistory.rs index 285b795f3..ca4bc9507 100644 --- a/src/keyhistory.rs +++ b/src/keyhistory.rs @@ -1,12 +1,11 @@ use crate::context::Context; -use crate::types::*; /* yes: uppercase */ /* library private: key-history */ pub fn dc_add_to_keyhistory( _context: &Context, _rfc724_mid: *const libc::c_char, - _sending_time: time_t, + _sending_time: u64, _addr: *const libc::c_char, _fingerprint: *const libc::c_char, ) { diff --git a/src/oauth2.rs b/src/oauth2.rs index 5eafa3a7e..f4bbd7e95 100644 --- a/src/oauth2.rs +++ b/src/oauth2.rs @@ -9,7 +9,6 @@ use crate::dc_log::*; use crate::dc_sqlite3::*; use crate::dc_tools::*; use crate::types::*; -use crate::x::*; const OAUTH2_GMAIL: Oauth2 = Oauth2 { client_id: "959970109878-4mvtgf6feshskf7695nfln6002mom908.apps.googleusercontent.com", @@ -171,9 +170,9 @@ pub fn dc_get_oauth2_access_token( let expires_in = response .expires_in // refresh a bet before - .map(|t| unsafe { time(0 as *mut time_t) as u64 } + t - 5) + .map(|t| time() + t as i64 - 5) .unwrap_or_else(|| 0); - set_config_int64(context, "oauth2_timestamp_expires", expires_in as i64); + set_config_int64(context, "oauth2_timestamp_expires", expires_in); if update_redirect_uri_on_success { set_config(context, "oauth2_redirect_uri", redirect_uri.as_ref()); @@ -342,12 +341,12 @@ fn is_expired(context: &Context) -> bool { b"oauth2_timestamp_expires\x00" as *const u8 as *const libc::c_char, 0i32 as int64_t, ) - } as time_t; + } as i64; if expire_timestamp <= 0 { return false; } - if expire_timestamp > unsafe { time(0 as *mut time_t) } { + if expire_timestamp > time() { return false; } diff --git a/src/types.rs b/src/types.rs index 53037ef40..bb9a03af0 100644 --- a/src/types.rs +++ b/src/types.rs @@ -68,7 +68,6 @@ pub type __uint16_t = libc::uint16_t; pub type __int32_t = libc::int32_t; pub type __uint64_t = libc::uint64_t; -pub type time_t = libc::time_t; pub type pid_t = libc::pid_t; pub type size_t = libc::size_t; pub type ssize_t = libc::ssize_t; diff --git a/src/x.rs b/src/x.rs index 205c789ca..5e1000da5 100644 --- a/src/x.rs +++ b/src/x.rs @@ -3,10 +3,9 @@ use crate::types::*; pub use libc::{ atoi, calloc, close, closedir, exit, fclose, fgets, fopen, fread, free, fseek, ftell, fwrite, - gmtime, gmtime_r, localtime, localtime_r, malloc, memcmp, memcpy, memmove, memset, mkdir, open, - opendir, printf, read, readdir, realloc, remove, sprintf, sscanf, strcat, strchr, strcmp, - strcpy, strcspn, strlen, strncmp, strncpy, strrchr, strspn, strstr, strtol, system, time, - tolower, write, + malloc, memcmp, memcpy, memmove, memset, mkdir, open, opendir, printf, read, readdir, realloc, + remove, sprintf, sscanf, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncmp, strncpy, + strrchr, strspn, strstr, strtol, system, tolower, write, }; pub unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char {