mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
5
.gitignore
vendored
5
.gitignore
vendored
@@ -7,4 +7,7 @@ Cargo.lock
|
|||||||
*.swp
|
*.swp
|
||||||
*.swo
|
*.swo
|
||||||
|
|
||||||
include
|
include
|
||||||
|
.dc-history.txt
|
||||||
|
*.db
|
||||||
|
*.db-blobs
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ percent-encoding = "1.0"
|
|||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
chrono = "0.4.6"
|
chrono = "0.4.6"
|
||||||
|
failure = "0.1.5"
|
||||||
|
# TODO: make optional
|
||||||
|
rustyline = "4.1.0"
|
||||||
|
lazy_static = "1.3.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3.0"
|
tempfile = "3.0"
|
||||||
|
|||||||
31
README.md
31
README.md
@@ -2,27 +2,10 @@
|
|||||||
|
|
||||||
> Project porting deltachat-core to rust
|
> Project porting deltachat-core to rust
|
||||||
|
|
||||||
|
|
||||||
[![CircleCI build status][circle-shield]][circle] [![Appveyor build status][appveyor-shield]][appveyor]
|
[![CircleCI build status][circle-shield]][circle] [![Appveyor build status][appveyor-shield]][appveyor]
|
||||||
|
|
||||||
Current commit on deltachat/deltachat-core: `12ef73c8e76185f9b78e844ea673025f56a959ab`.
|
Current commit on deltachat/deltachat-core: `12ef73c8e76185f9b78e844ea673025f56a959ab`.
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# run example
|
|
||||||
$ cargo run --example simple
|
|
||||||
# build c-ffi
|
|
||||||
$ cargo build -p deltachat_ffi --release
|
|
||||||
# run tests
|
|
||||||
$ cargo test --all
|
|
||||||
```
|
|
||||||
|
|
||||||
[circle-shield]: https://img.shields.io/circleci/project/github/deltachat/deltachat-core-rust/master.svg?style=flat-square
|
|
||||||
[circle]: https://circleci.com/gh/deltachat/deltachat-core-rust/
|
|
||||||
[appveyor-shield]: https://ci.appveyor.com/api/projects/status/lqpegel3ld4ipxj8/branch/master?style=flat-square
|
|
||||||
[appveyor]: https://ci.appveyor.com/project/dignifiedquire/deltachat-core-rust/branch/master
|
|
||||||
|
|
||||||
## Using the CLI client
|
## Using the CLI client
|
||||||
|
|
||||||
Run using `cargo`:
|
Run using `cargo`:
|
||||||
@@ -73,3 +56,17 @@ For more commands type `> help`.
|
|||||||
```
|
```
|
||||||
> help
|
> help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# run tests
|
||||||
|
$ cargo test --all
|
||||||
|
# build c-ffi
|
||||||
|
$ cargo build -p deltachat_ffi --release
|
||||||
|
```
|
||||||
|
|
||||||
|
[circle-shield]: https://img.shields.io/circleci/project/github/deltachat/deltachat-core-rust/master.svg?style=flat-square
|
||||||
|
[circle]: https://circleci.com/gh/deltachat/deltachat-core-rust/
|
||||||
|
[appveyor-shield]: https://ci.appveyor.com/api/projects/status/lqpegel3ld4ipxj8/branch/master?style=flat-square
|
||||||
|
[appveyor]: https://ci.appveyor.com/project/dignifiedquire/deltachat-core-rust/branch/master
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +1,19 @@
|
|||||||
//! This is a CLI program and a little testing frame. This file must not be
|
//! This is a CLI program and a little testing frame. This file must not be
|
||||||
//! included when using Delta Chat Core as a library.
|
//! included when using Delta Chat Core as a library.
|
||||||
//!
|
//!
|
||||||
//! Usage: messenger-backend <databasefile>
|
//! Usage: cargo run --example repl --release -- <databasefile>
|
||||||
//! (for "Code::Blocks, use Project / Set programs' arguments")
|
//! All further options can be set using the set-command (type ? for help).
|
||||||
//! all further options can be set using the set-command (type ? for help).
|
|
||||||
|
|
||||||
#![allow(
|
#[macro_use]
|
||||||
mutable_transmutes,
|
extern crate deltachat;
|
||||||
non_camel_case_types,
|
#[macro_use]
|
||||||
non_snake_case,
|
extern crate failure;
|
||||||
non_upper_case_globals,
|
#[macro_use]
|
||||||
non_upper_case_globals,
|
extern crate lazy_static;
|
||||||
non_camel_case_types,
|
|
||||||
non_snake_case
|
|
||||||
)]
|
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::borrow::Cow::{self, Borrowed, Owned};
|
||||||
use std::io::{self, Write};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
|
|
||||||
use deltachat::constants::*;
|
use deltachat::constants::*;
|
||||||
use deltachat::context::*;
|
use deltachat::context::*;
|
||||||
@@ -28,13 +24,19 @@ use deltachat::dc_tools::*;
|
|||||||
use deltachat::oauth2::*;
|
use deltachat::oauth2::*;
|
||||||
use deltachat::types::*;
|
use deltachat::types::*;
|
||||||
use deltachat::x::*;
|
use deltachat::x::*;
|
||||||
|
use rustyline::completion::{Completer, FilenameCompleter, Pair};
|
||||||
|
use rustyline::config::OutputStreamType;
|
||||||
|
use rustyline::error::ReadlineError;
|
||||||
|
use rustyline::highlight::{Highlighter, MatchingBracketHighlighter};
|
||||||
|
use rustyline::hint::{Hinter, HistoryHinter};
|
||||||
|
use rustyline::{
|
||||||
|
Cmd, CompletionType, Config, Context as RustyContext, EditMode, Editor, Helper, KeyPress,
|
||||||
|
};
|
||||||
|
|
||||||
mod cmdline;
|
mod cmdline;
|
||||||
use self::cmdline::*;
|
use self::cmdline::*;
|
||||||
|
|
||||||
/* ******************************************************************************
|
// Event Handler
|
||||||
* Event Handler
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
unsafe extern "C" fn receive_event(
|
unsafe extern "C" fn receive_event(
|
||||||
_context: &Context,
|
_context: &Context,
|
||||||
@@ -42,259 +44,475 @@ unsafe extern "C" fn receive_event(
|
|||||||
data1: uintptr_t,
|
data1: uintptr_t,
|
||||||
data2: uintptr_t,
|
data2: uintptr_t,
|
||||||
) -> uintptr_t {
|
) -> uintptr_t {
|
||||||
match event as u32 {
|
match event {
|
||||||
2091 => {}
|
Event::GET_STRING => {}
|
||||||
100 => {
|
Event::INFO => {
|
||||||
/* do not show the event as this would fill the screen */
|
/* do not show the event as this would fill the screen */
|
||||||
println!("{}", to_string(data2 as *const _),);
|
println!("{}", to_string(data2 as *const _),);
|
||||||
}
|
}
|
||||||
101 => {
|
Event::SMTP_CONNECTED => {
|
||||||
println!("[DC_EVENT_SMTP_CONNECTED] {}", to_string(data2 as *const _));
|
println!("[DC_EVENT_SMTP_CONNECTED] {}", to_string(data2 as *const _));
|
||||||
}
|
}
|
||||||
102 => {
|
Event::IMAP_CONNECTED => {
|
||||||
println!("[DC_EVENT_IMAP_CONNECTED] {}", to_string(data2 as *const _),);
|
println!("[DC_EVENT_IMAP_CONNECTED] {}", to_string(data2 as *const _),);
|
||||||
}
|
}
|
||||||
103 => {
|
Event::SMTP_MESSAGE_SENT => {
|
||||||
println!(
|
println!(
|
||||||
"[DC_EVENT_SMTP_MESSAGE_SENT] {}",
|
"[DC_EVENT_SMTP_MESSAGE_SENT] {}",
|
||||||
to_string(data2 as *const _),
|
to_string(data2 as *const _),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
300 => {
|
Event::WARNING => {
|
||||||
println!("[Warning] {}", to_string(data2 as *const _),);
|
println!("[Warning] {}", to_string(data2 as *const _),);
|
||||||
}
|
}
|
||||||
400 => {
|
Event::ERROR => {
|
||||||
println!(
|
println!(
|
||||||
"\x1b[31m[DC_EVENT_ERROR] {}\x1b[0m",
|
"\x1b[31m[DC_EVENT_ERROR] {}\x1b[0m",
|
||||||
to_string(data2 as *const _),
|
to_string(data2 as *const _),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
401 => {
|
Event::ERROR_NETWORK => {
|
||||||
println!(
|
println!(
|
||||||
"\x1b[31m[DC_EVENT_ERROR_NETWORK] first={}, msg={}\x1b[0m",
|
"\x1b[31m[DC_EVENT_ERROR_NETWORK] first={}, msg={}\x1b[0m",
|
||||||
data1 as libc::c_int,
|
data1 as usize,
|
||||||
to_string(data2 as *const _),
|
to_string(data2 as *const _),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
410 => {
|
Event::ERROR_SELF_NOT_IN_GROUP => {
|
||||||
println!(
|
println!(
|
||||||
"\x1b[31m[DC_EVENT_ERROR_SELF_NOT_IN_GROUP] {}\x1b[0m",
|
"\x1b[31m[DC_EVENT_ERROR_SELF_NOT_IN_GROUP] {}\x1b[0m",
|
||||||
to_string(data2 as *const _),
|
to_string(data2 as *const _),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
2081 => {
|
Event::MSGS_CHANGED => {
|
||||||
print!("\x1b[33m{{Received DC_EVENT_IS_OFFLINE()}}\n\x1b[0m");
|
|
||||||
}
|
|
||||||
2000 => {
|
|
||||||
print!(
|
print!(
|
||||||
"\x1b[33m{{Received DC_EVENT_MSGS_CHANGED({}, {})}}\n\x1b[0m",
|
"\x1b[33m{{Received DC_EVENT_MSGS_CHANGED({}, {})}}\n\x1b[0m",
|
||||||
data1 as libc::c_int, data2 as libc::c_int,
|
data1 as usize, data2 as usize,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
2030 => {
|
Event::CONTACTS_CHANGED => {
|
||||||
print!("\x1b[33m{{Received DC_EVENT_CONTACTS_CHANGED()}}\n\x1b[0m");
|
print!("\x1b[33m{{Received DC_EVENT_CONTACTS_CHANGED()}}\n\x1b[0m");
|
||||||
}
|
}
|
||||||
2035 => {
|
Event::LOCATION_CHANGED => {
|
||||||
print!(
|
print!(
|
||||||
"\x1b[33m{{Received DC_EVENT_LOCATION_CHANGED(contact={})}}\n\x1b[0m",
|
"\x1b[33m{{Received DC_EVENT_LOCATION_CHANGED(contact={})}}\n\x1b[0m",
|
||||||
data1 as libc::c_int,
|
data1 as usize,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
2041 => {
|
Event::CONFIGURE_PROGRESS => {
|
||||||
print!(
|
print!(
|
||||||
"\x1b[33m{{Received DC_EVENT_CONFIGURE_PROGRESS({} ‰)}}\n\x1b[0m",
|
"\x1b[33m{{Received DC_EVENT_CONFIGURE_PROGRESS({} ‰)}}\n\x1b[0m",
|
||||||
data1 as libc::c_int,
|
data1 as usize,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
2051 => {
|
Event::IMEX_PROGRESS => {
|
||||||
print!(
|
print!(
|
||||||
"\x1b[33m{{Received DC_EVENT_IMEX_PROGRESS({} ‰)}}\n\x1b[0m",
|
"\x1b[33m{{Received DC_EVENT_IMEX_PROGRESS({} ‰)}}\n\x1b[0m",
|
||||||
data1 as libc::c_int,
|
data1 as usize,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
2052 => {
|
Event::IMEX_FILE_WRITTEN => {
|
||||||
print!(
|
print!(
|
||||||
"\x1b[33m{{Received DC_EVENT_IMEX_FILE_WRITTEN({})}}\n\x1b[0m",
|
"\x1b[33m{{Received DC_EVENT_IMEX_FILE_WRITTEN({})}}\n\x1b[0m",
|
||||||
to_string(data1 as *const _)
|
to_string(data1 as *const _)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
2055 => {
|
Event::CHAT_MODIFIED => {
|
||||||
print!(
|
|
||||||
"\x1b[33m{{Received DC_EVENT_FILE_COPIED({})}}\n\x1b[0m",
|
|
||||||
to_string(data1 as *const _)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
2020 => {
|
|
||||||
print!(
|
print!(
|
||||||
"\x1b[33m{{Received DC_EVENT_CHAT_MODIFIED({})}}\n\x1b[0m",
|
"\x1b[33m{{Received DC_EVENT_CHAT_MODIFIED({})}}\n\x1b[0m",
|
||||||
data1 as libc::c_int,
|
data1 as usize,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
print!(
|
print!(
|
||||||
"\x1b[33m{{Received DC_EVENT_{}({}, {})}}\n\x1b[0m",
|
"\x1b[33m{{Received {:?}({}, {})}}\n\x1b[0m",
|
||||||
event as libc::c_int, data1 as libc::c_int, data2 as libc::c_int,
|
event, data1 as usize, data2 as usize,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0i32 as uintptr_t;
|
|
||||||
}
|
|
||||||
/* ******************************************************************************
|
|
||||||
* Threads for waiting for messages and for jobs
|
|
||||||
******************************************************************************/
|
|
||||||
static mut run_threads: libc::c_int = 0i32;
|
|
||||||
|
|
||||||
unsafe fn start_threads(
|
0
|
||||||
c: Arc<RwLock<Context>>,
|
}
|
||||||
) -> (
|
|
||||||
std::thread::JoinHandle<()>,
|
// Threads for waiting for messages and for jobs
|
||||||
std::thread::JoinHandle<()>,
|
|
||||||
std::thread::JoinHandle<()>,
|
lazy_static! {
|
||||||
std::thread::JoinHandle<()>,
|
static ref HANDLE: Arc<Mutex<Option<Handle>>> = Arc::new(Mutex::new(None));
|
||||||
) {
|
static ref IS_RUNNING: AtomicBool = AtomicBool::new(true);
|
||||||
run_threads = 1;
|
}
|
||||||
|
|
||||||
|
struct Handle {
|
||||||
|
handle_imap: Option<std::thread::JoinHandle<()>>,
|
||||||
|
handle_mvbox: Option<std::thread::JoinHandle<()>>,
|
||||||
|
handle_sentbox: Option<std::thread::JoinHandle<()>>,
|
||||||
|
handle_smtp: Option<std::thread::JoinHandle<()>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! while_running {
|
||||||
|
($code:block) => {
|
||||||
|
if IS_RUNNING.load(Ordering::Relaxed) {
|
||||||
|
$code
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_threads(c: Arc<RwLock<Context>>) {
|
||||||
|
if HANDLE.clone().lock().unwrap().is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Starting threads");
|
||||||
|
IS_RUNNING.store(true, Ordering::Relaxed);
|
||||||
|
|
||||||
let ctx = c.clone();
|
let ctx = c.clone();
|
||||||
let h1 = std::thread::spawn(move || {
|
let handle_imap = std::thread::spawn(move || loop {
|
||||||
let context = ctx.read().unwrap();
|
while_running!({
|
||||||
while 0 != run_threads {
|
unsafe {
|
||||||
dc_perform_imap_jobs(&context);
|
dc_perform_imap_jobs(&ctx.read().unwrap());
|
||||||
dc_perform_imap_fetch(&context);
|
dc_perform_imap_fetch(&ctx.read().unwrap());
|
||||||
if 0 != run_threads {
|
}
|
||||||
|
while_running!({
|
||||||
|
let context = ctx.read().unwrap();
|
||||||
dc_perform_imap_idle(&context);
|
dc_perform_imap_idle(&context);
|
||||||
}
|
});
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let ctx = c.clone();
|
let ctx = c.clone();
|
||||||
let h2 = std::thread::spawn(move || {
|
let handle_mvbox = std::thread::spawn(move || loop {
|
||||||
let context = ctx.read().unwrap();
|
while_running!({
|
||||||
while 0 != run_threads {
|
unsafe { dc_perform_mvbox_fetch(&ctx.read().unwrap()) };
|
||||||
dc_perform_mvbox_fetch(&context);
|
while_running!({
|
||||||
if 0 != run_threads {
|
unsafe { dc_perform_mvbox_idle(&ctx.read().unwrap()) };
|
||||||
dc_perform_mvbox_idle(&context);
|
});
|
||||||
}
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let ctx = c.clone();
|
let ctx = c.clone();
|
||||||
let h3 = std::thread::spawn(move || {
|
let handle_sentbox = std::thread::spawn(move || loop {
|
||||||
let context = ctx.read().unwrap();
|
while_running!({
|
||||||
while 0 != run_threads {
|
unsafe { dc_perform_sentbox_fetch(&ctx.read().unwrap()) };
|
||||||
dc_perform_sentbox_fetch(&context);
|
while_running!({
|
||||||
if 0 != run_threads {
|
unsafe { dc_perform_sentbox_idle(&ctx.read().unwrap()) };
|
||||||
dc_perform_sentbox_idle(&context);
|
});
|
||||||
}
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let ctx = c.clone();
|
let ctx = c;
|
||||||
let h4 = std::thread::spawn(move || {
|
let handle_smtp = std::thread::spawn(move || loop {
|
||||||
let context = ctx.read().unwrap();
|
while_running!({
|
||||||
while 0 != run_threads {
|
unsafe { dc_perform_smtp_jobs(&ctx.read().unwrap()) };
|
||||||
dc_perform_smtp_jobs(&context);
|
while_running!({
|
||||||
if 0 != run_threads {
|
unsafe { dc_perform_smtp_idle(&ctx.read().unwrap()) };
|
||||||
dc_perform_smtp_idle(&context);
|
});
|
||||||
}
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
(h1, h2, h3, h4)
|
*HANDLE.clone().lock().unwrap() = Some(Handle {
|
||||||
|
handle_imap: Some(handle_imap),
|
||||||
|
handle_mvbox: Some(handle_mvbox),
|
||||||
|
handle_sentbox: Some(handle_sentbox),
|
||||||
|
handle_smtp: Some(handle_smtp),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn stop_threads(
|
fn stop_threads(context: &Context) {
|
||||||
context: &Context,
|
if let Some(ref mut handle) = *HANDLE.clone().lock().unwrap() {
|
||||||
handles: Option<(
|
println!("Stopping threads");
|
||||||
std::thread::JoinHandle<()>,
|
IS_RUNNING.store(false, Ordering::Relaxed);
|
||||||
std::thread::JoinHandle<()>,
|
|
||||||
std::thread::JoinHandle<()>,
|
unsafe {
|
||||||
std::thread::JoinHandle<()>,
|
dc_interrupt_imap_idle(context);
|
||||||
)>,
|
dc_interrupt_mvbox_idle(context);
|
||||||
) {
|
dc_interrupt_sentbox_idle(context);
|
||||||
run_threads = 0i32;
|
dc_interrupt_smtp_idle(context);
|
||||||
dc_interrupt_imap_idle(context);
|
}
|
||||||
dc_interrupt_mvbox_idle(context);
|
|
||||||
dc_interrupt_sentbox_idle(context);
|
handle.handle_imap.take().unwrap().join().unwrap();
|
||||||
dc_interrupt_smtp_idle(context);
|
handle.handle_mvbox.take().unwrap().join().unwrap();
|
||||||
if let Some((h1, h2, h3, h4)) = handles {
|
handle.handle_sentbox.take().unwrap().join().unwrap();
|
||||||
h1.join().unwrap();
|
handle.handle_smtp.take().unwrap().join().unwrap();
|
||||||
h2.join().unwrap();
|
|
||||||
h3.join().unwrap();
|
|
||||||
h4.join().unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ******************************************************************************
|
// === The main loop
|
||||||
* The main loop
|
|
||||||
******************************************************************************/
|
|
||||||
fn read_cmd() -> String {
|
|
||||||
print!("> ");
|
|
||||||
io::stdout().flush().unwrap();
|
|
||||||
|
|
||||||
let mut input = String::new();
|
struct DcHelper {
|
||||||
io::stdin().read_line(&mut input).unwrap();
|
completer: FilenameCompleter,
|
||||||
input.trim_end().to_string()
|
highlighter: MatchingBracketHighlighter,
|
||||||
|
hinter: HistoryHinter,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn main_0(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int {
|
impl Completer for DcHelper {
|
||||||
let mut cmd: *mut libc::c_char = 0 as *mut libc::c_char;
|
type Candidate = Pair;
|
||||||
|
|
||||||
|
fn complete(
|
||||||
|
&self,
|
||||||
|
line: &str,
|
||||||
|
pos: usize,
|
||||||
|
ctx: &RustyContext<'_>,
|
||||||
|
) -> Result<(usize, Vec<Pair>), ReadlineError> {
|
||||||
|
self.completer.complete(line, pos, ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const IMEX_COMMANDS: [&'static str; 12] = [
|
||||||
|
"initiate-key-transfer",
|
||||||
|
"get-setupcodebegin",
|
||||||
|
"continue-key-transfer",
|
||||||
|
"has-backup",
|
||||||
|
"export-backup",
|
||||||
|
"import-backup",
|
||||||
|
"export-keys",
|
||||||
|
"import-keys",
|
||||||
|
"export-setup",
|
||||||
|
"poke",
|
||||||
|
"reset",
|
||||||
|
"stop",
|
||||||
|
];
|
||||||
|
|
||||||
|
const DB_COMMANDS: [&'static str; 11] = [
|
||||||
|
"info",
|
||||||
|
"open",
|
||||||
|
"close",
|
||||||
|
"set",
|
||||||
|
"get",
|
||||||
|
"oauth2",
|
||||||
|
"configure",
|
||||||
|
"connect",
|
||||||
|
"disconnect",
|
||||||
|
"maybenetwork",
|
||||||
|
"housekeeping",
|
||||||
|
];
|
||||||
|
|
||||||
|
const CHAT_COMMANDS: [&'static str; 24] = [
|
||||||
|
"listchats",
|
||||||
|
"listarchived",
|
||||||
|
"chat",
|
||||||
|
"createchat",
|
||||||
|
"createchatbymsg",
|
||||||
|
"creategroup",
|
||||||
|
"createverified",
|
||||||
|
"addmember",
|
||||||
|
"removemember",
|
||||||
|
"groupname",
|
||||||
|
"groupimage",
|
||||||
|
"chatinfo",
|
||||||
|
"sendlocations",
|
||||||
|
"setlocation",
|
||||||
|
"dellocations",
|
||||||
|
"getlocations",
|
||||||
|
"send",
|
||||||
|
"sendimage",
|
||||||
|
"sendfile",
|
||||||
|
"draft",
|
||||||
|
"listmedia",
|
||||||
|
"archive",
|
||||||
|
"unarchive",
|
||||||
|
"delchat",
|
||||||
|
];
|
||||||
|
const MESSAGE_COMMANDS: [&'static str; 8] = [
|
||||||
|
"listmsgs",
|
||||||
|
"msginfo",
|
||||||
|
"listfresh",
|
||||||
|
"forward",
|
||||||
|
"markseen",
|
||||||
|
"star",
|
||||||
|
"unstar",
|
||||||
|
"delmsg",
|
||||||
|
];
|
||||||
|
const CONTACT_COMMANDS: [&'static str; 6] = [
|
||||||
|
"listcontacts",
|
||||||
|
"listverified",
|
||||||
|
"addcontact",
|
||||||
|
"contactinfo",
|
||||||
|
"delcontact",
|
||||||
|
"cleanupcontacts",
|
||||||
|
];
|
||||||
|
const MISC_COMMANDS: [&'static str; 8] = [
|
||||||
|
"getqr", "getbadqr", "checkqr", "event", "fileinfo", "clear", "exit", "help",
|
||||||
|
];
|
||||||
|
|
||||||
|
impl Hinter for DcHelper {
|
||||||
|
fn hint(&self, line: &str, pos: usize, ctx: &RustyContext<'_>) -> Option<String> {
|
||||||
|
if !line.is_empty() {
|
||||||
|
for &cmds in &[
|
||||||
|
&IMEX_COMMANDS[..],
|
||||||
|
&DB_COMMANDS[..],
|
||||||
|
&CHAT_COMMANDS[..],
|
||||||
|
&MESSAGE_COMMANDS[..],
|
||||||
|
&CONTACT_COMMANDS[..],
|
||||||
|
&MISC_COMMANDS[..],
|
||||||
|
] {
|
||||||
|
if let Some(entry) = cmds.iter().find(|el| el.starts_with(&line[..pos])) {
|
||||||
|
if *entry != line && *entry != &line[..pos] {
|
||||||
|
return Some(entry[pos..].to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.hinter.hint(line, pos, ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static COLORED_PROMPT: &'static str = "\x1b[1;32m> \x1b[0m";
|
||||||
|
static PROMPT: &'static str = "> ";
|
||||||
|
|
||||||
|
impl Highlighter for DcHelper {
|
||||||
|
fn highlight_prompt<'p>(&self, prompt: &'p str) -> Cow<'p, str> {
|
||||||
|
if prompt == PROMPT {
|
||||||
|
Borrowed(COLORED_PROMPT)
|
||||||
|
} else {
|
||||||
|
Borrowed(prompt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
|
||||||
|
Owned("\x1b[1m".to_owned() + hint + "\x1b[m")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn highlight<'l>(&self, line: &'l str, pos: usize) -> Cow<'l, str> {
|
||||||
|
self.highlighter.highlight(line, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn highlight_char(&self, line: &str, pos: usize) -> bool {
|
||||||
|
self.highlighter.highlight_char(line, pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Helper for DcHelper {}
|
||||||
|
|
||||||
|
fn main_0(args: Vec<String>) -> Result<(), failure::Error> {
|
||||||
let mut context = dc_context_new(
|
let mut context = dc_context_new(
|
||||||
receive_event,
|
receive_event,
|
||||||
0 as *mut libc::c_void,
|
0 as *mut libc::c_void,
|
||||||
b"CLI\x00" as *const u8 as *const libc::c_char,
|
b"CLI\x00" as *const u8 as *const libc::c_char,
|
||||||
);
|
);
|
||||||
|
|
||||||
dc_cmdline_skip_auth();
|
unsafe { dc_cmdline_skip_auth() };
|
||||||
|
|
||||||
if argc == 2i32 {
|
if args.len() == 2 {
|
||||||
if 0 == dc_open(&mut context, *argv.offset(1isize), 0 as *const libc::c_char) {
|
if 0 == unsafe {
|
||||||
println!(
|
dc_open(
|
||||||
"ERROR: Cannot open {}.",
|
&mut context,
|
||||||
to_string(*argv.offset(1isize) as *const _)
|
to_cstring(&args[1]).as_ptr(),
|
||||||
);
|
0 as *const libc::c_char,
|
||||||
|
)
|
||||||
|
} {
|
||||||
|
println!("Error: Cannot open {}.", args[0],);
|
||||||
}
|
}
|
||||||
} else if argc != 1i32 {
|
} else if args.len() != 1 {
|
||||||
println!("ERROR: Bad arguments");
|
println!("Error: Bad arguments, expected [db-name].");
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Delta Chat Core is awaiting your commands.");
|
println!("Delta Chat Core is awaiting your commands.");
|
||||||
|
|
||||||
let mut handles = None;
|
|
||||||
|
|
||||||
let ctx = Arc::new(RwLock::new(context));
|
let ctx = Arc::new(RwLock::new(context));
|
||||||
|
|
||||||
|
let config = Config::builder()
|
||||||
|
.history_ignore_space(true)
|
||||||
|
.completion_type(CompletionType::List)
|
||||||
|
.edit_mode(EditMode::Emacs)
|
||||||
|
.output_stream(OutputStreamType::Stdout)
|
||||||
|
.build();
|
||||||
|
let h = DcHelper {
|
||||||
|
completer: FilenameCompleter::new(),
|
||||||
|
highlighter: MatchingBracketHighlighter::new(),
|
||||||
|
hinter: HistoryHinter {},
|
||||||
|
};
|
||||||
|
let mut rl = Editor::with_config(config);
|
||||||
|
rl.set_helper(Some(h));
|
||||||
|
rl.bind_sequence(KeyPress::Meta('N'), Cmd::HistorySearchForward);
|
||||||
|
rl.bind_sequence(KeyPress::Meta('P'), Cmd::HistorySearchBackward);
|
||||||
|
if rl.load_history(".dc-history.txt").is_err() {
|
||||||
|
println!("No previous history.");
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
/* read command */
|
let p = "> ";
|
||||||
let cmdline = read_cmd();
|
let readline = rl.readline(&p);
|
||||||
free(cmd as *mut libc::c_void);
|
match readline {
|
||||||
cmd = dc_strdup(CString::new(cmdline.clone()).unwrap().as_ptr());
|
Ok(line) => {
|
||||||
let mut arg1: *mut libc::c_char = strchr(cmd, ' ' as i32);
|
// TODO: ignore "set mail_pw"
|
||||||
if !arg1.is_null() {
|
rl.add_history_entry(line.as_str());
|
||||||
*arg1 = 0i32 as libc::c_char;
|
let ctx = ctx.clone();
|
||||||
arg1 = arg1.offset(1isize)
|
match unsafe { handle_cmd(line.trim(), ctx) } {
|
||||||
|
Ok(ExitResult::Continue) => {}
|
||||||
|
Ok(ExitResult::Exit) => break,
|
||||||
|
Err(err) => println!("Error: {}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(ReadlineError::Interrupted) | Err(ReadlineError::Eof) => {
|
||||||
|
println!("Exiting...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
println!("Error: {}", err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if strcmp(cmd, b"connect\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
}
|
||||||
handles = Some(start_threads(ctx.clone()));
|
rl.save_history(".dc-history.txt")?;
|
||||||
} else if strcmp(cmd, b"disconnect\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
println!("history saved");
|
||||||
stop_threads(&ctx.read().unwrap(), handles);
|
{
|
||||||
handles = None;
|
stop_threads(&ctx.read().unwrap());
|
||||||
} else if strcmp(cmd, b"smtp-jobs\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
|
||||||
if 0 != run_threads {
|
unsafe {
|
||||||
|
let mut ctx = ctx.write().unwrap();
|
||||||
|
dc_close(&mut ctx);
|
||||||
|
dc_context_unref(&mut ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum ExitResult {
|
||||||
|
Continue,
|
||||||
|
Exit,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult, failure::Error> {
|
||||||
|
let mut args = line.splitn(2, ' ');
|
||||||
|
let arg0 = args.next().unwrap_or_default();
|
||||||
|
let arg1 = args.next().unwrap_or_default();
|
||||||
|
let arg1_c = to_cstring(arg1);
|
||||||
|
let arg1_c_ptr = if arg1.is_empty() {
|
||||||
|
std::ptr::null()
|
||||||
|
} else {
|
||||||
|
arg1_c.as_ptr()
|
||||||
|
};
|
||||||
|
|
||||||
|
match arg0 {
|
||||||
|
"connect" => {
|
||||||
|
start_threads(ctx);
|
||||||
|
}
|
||||||
|
"disconnect" => {
|
||||||
|
stop_threads(&ctx.read().unwrap());
|
||||||
|
}
|
||||||
|
"smtp-jobs" => {
|
||||||
|
if HANDLE.clone().lock().unwrap().is_some() {
|
||||||
println!("smtp-jobs are already running in a thread.",);
|
println!("smtp-jobs are already running in a thread.",);
|
||||||
} else {
|
} else {
|
||||||
dc_perform_smtp_jobs(&ctx.read().unwrap());
|
dc_perform_smtp_jobs(&ctx.read().unwrap());
|
||||||
}
|
}
|
||||||
} else if strcmp(cmd, b"imap-jobs\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
}
|
||||||
if 0 != run_threads {
|
"imap-jobs" => {
|
||||||
|
if HANDLE.clone().lock().unwrap().is_some() {
|
||||||
println!("imap-jobs are already running in a thread.");
|
println!("imap-jobs are already running in a thread.");
|
||||||
} else {
|
} else {
|
||||||
dc_perform_imap_jobs(&ctx.read().unwrap());
|
dc_perform_imap_jobs(&ctx.read().unwrap());
|
||||||
}
|
}
|
||||||
} else if strcmp(cmd, b"configure\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
}
|
||||||
handles = { Some(start_threads(ctx.clone())) };
|
"configure" => {
|
||||||
|
start_threads(ctx.clone());
|
||||||
dc_configure(&ctx.read().unwrap());
|
dc_configure(&ctx.read().unwrap());
|
||||||
} else if strcmp(cmd, b"oauth2\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
}
|
||||||
let addr: *mut libc::c_char = dc_get_config(
|
"oauth2" => {
|
||||||
|
let addr = dc_get_config(
|
||||||
&ctx.read().unwrap(),
|
&ctx.read().unwrap(),
|
||||||
b"addr\x00" as *const u8 as *const libc::c_char,
|
b"addr\x00" as *const u8 as *const libc::c_char,
|
||||||
);
|
);
|
||||||
@@ -313,21 +531,17 @@ unsafe fn main_0(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(addr as *mut libc::c_void);
|
free(addr as *mut libc::c_void);
|
||||||
} else if strcmp(cmd, b"clear\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
}
|
||||||
|
"clear" => {
|
||||||
println!("\n\n\n");
|
println!("\n\n\n");
|
||||||
print!("\x1b[1;1H\x1b[2J");
|
print!("\x1b[1;1H\x1b[2J");
|
||||||
} else if strcmp(cmd, b"getqr\x00" as *const u8 as *const libc::c_char) == 0i32
|
}
|
||||||
|| strcmp(cmd, b"getbadqr\x00" as *const u8 as *const libc::c_char) == 0i32
|
"getqr" | "getbadqr" => {
|
||||||
{
|
start_threads(ctx.clone());
|
||||||
handles = Some(start_threads(ctx.clone()));
|
let qrstr =
|
||||||
let qrstr: *mut libc::c_char = dc_get_securejoin_qr(
|
dc_get_securejoin_qr(&ctx.read().unwrap(), arg1.parse().unwrap_or_default());
|
||||||
&ctx.read().unwrap(),
|
|
||||||
(if !arg1.is_null() { atoi(arg1) } else { 0i32 }) as uint32_t,
|
|
||||||
);
|
|
||||||
if !qrstr.is_null() && 0 != *qrstr.offset(0isize) as libc::c_int {
|
if !qrstr.is_null() && 0 != *qrstr.offset(0isize) as libc::c_int {
|
||||||
if strcmp(cmd, b"getbadqr\x00" as *const u8 as *const libc::c_char) == 0i32
|
if arg0 == "getbadqr" && strlen(qrstr) > 40 {
|
||||||
&& strlen(qrstr) > 40
|
|
||||||
{
|
|
||||||
let mut i: libc::c_int = 12i32;
|
let mut i: libc::c_int = 12i32;
|
||||||
while i < 22i32 {
|
while i < 22i32 {
|
||||||
*qrstr.offset(i as isize) = '0' as i32 as libc::c_char;
|
*qrstr.offset(i as isize) = '0' as i32 as libc::c_char;
|
||||||
@@ -335,7 +549,7 @@ unsafe fn main_0(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("{}", to_string(qrstr as *const _));
|
println!("{}", to_string(qrstr as *const _));
|
||||||
let syscmd: *mut libc::c_char = dc_mprintf(
|
let syscmd = dc_mprintf(
|
||||||
b"qrencode -t ansiutf8 \"%s\" -o -\x00" as *const u8 as *const libc::c_char,
|
b"qrencode -t ansiutf8 \"%s\" -o -\x00" as *const u8 as *const libc::c_char,
|
||||||
qrstr,
|
qrstr,
|
||||||
);
|
);
|
||||||
@@ -343,55 +557,25 @@ unsafe fn main_0(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int
|
|||||||
free(syscmd as *mut libc::c_void);
|
free(syscmd as *mut libc::c_void);
|
||||||
}
|
}
|
||||||
free(qrstr as *mut libc::c_void);
|
free(qrstr as *mut libc::c_void);
|
||||||
} else if strcmp(cmd, b"joinqr\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
}
|
||||||
handles = Some(start_threads(ctx.clone()));
|
"joinqr" => {
|
||||||
if !arg1.is_null() {
|
start_threads(ctx.clone());
|
||||||
dc_join_securejoin(&ctx.read().unwrap(), arg1);
|
if !arg0.is_empty() {
|
||||||
}
|
dc_join_securejoin(&ctx.read().unwrap(), arg1_c_ptr);
|
||||||
} else {
|
|
||||||
if strcmp(cmd, b"exit\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if !(*cmd.offset(0isize) as libc::c_int == 0i32) {
|
|
||||||
let execute_result: *mut libc::c_char = dc_cmdline(&ctx.read().unwrap(), &cmdline);
|
|
||||||
if !execute_result.is_null() {
|
|
||||||
println!("{}", to_string(execute_result as *const _));
|
|
||||||
free(execute_result as *mut libc::c_void);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"exit" => return Ok(ExitResult::Exit),
|
||||||
|
_ => dc_cmdline(&ctx.read().unwrap(), line)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
let ctx = ctx.clone();
|
Ok(ExitResult::Continue)
|
||||||
|
|
||||||
{
|
|
||||||
let mut ctx = ctx.write().unwrap();
|
|
||||||
free(cmd as *mut libc::c_void);
|
|
||||||
stop_threads(&ctx, handles);
|
|
||||||
dc_close(&mut ctx);
|
|
||||||
dc_context_unref(&mut ctx);
|
|
||||||
}
|
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() -> Result<(), failure::Error> {
|
||||||
let _ = pretty_env_logger::try_init();
|
let _ = pretty_env_logger::try_init();
|
||||||
|
|
||||||
let mut args: Vec<*mut libc::c_char> = Vec::new();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
for arg in ::std::env::args() {
|
main_0(args)?;
|
||||||
args.push(
|
|
||||||
::std::ffi::CString::new(arg)
|
|
||||||
.expect("Failed to convert argument into CString.")
|
|
||||||
.into_raw(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
args.push(::std::ptr::null_mut());
|
|
||||||
|
|
||||||
let res = unsafe {
|
Ok(())
|
||||||
main_0(
|
|
||||||
(args.len() - 1) as libc::c_int,
|
|
||||||
args.as_mut_ptr() as *mut *mut libc::c_char,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
::std::process::exit(res)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,7 @@ pub unsafe fn dc_array_add_uint(mut array: *mut dc_array_t, item: uintptr_t) {
|
|||||||
(*array).array as *mut libc::c_void,
|
(*array).array as *mut libc::c_void,
|
||||||
(newsize).wrapping_mul(::std::mem::size_of::<uintptr_t>()),
|
(newsize).wrapping_mul(::std::mem::size_of::<uintptr_t>()),
|
||||||
) as *mut uintptr_t;
|
) as *mut uintptr_t;
|
||||||
if (*array).array.is_null() {
|
assert!(!(*array).array.is_null());
|
||||||
exit(49i32);
|
|
||||||
}
|
|
||||||
(*array).allocated = newsize as size_t
|
(*array).allocated = newsize as size_t
|
||||||
}
|
}
|
||||||
*(*array).array.offset((*array).count as isize) = item;
|
*(*array).array.offset((*array).count as isize) = item;
|
||||||
@@ -266,9 +264,8 @@ pub unsafe fn dc_array_new(initsize: size_t) -> *mut dc_array_t {
|
|||||||
pub unsafe fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut dc_array_t {
|
pub unsafe fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut dc_array_t {
|
||||||
let mut array: *mut dc_array_t;
|
let mut array: *mut dc_array_t;
|
||||||
array = calloc(1, ::std::mem::size_of::<dc_array_t>()) as *mut dc_array_t;
|
array = calloc(1, ::std::mem::size_of::<dc_array_t>()) as *mut dc_array_t;
|
||||||
if array.is_null() {
|
assert!(!array.is_null());
|
||||||
exit(47i32);
|
|
||||||
}
|
|
||||||
(*array).magic = 0xa11aai32 as uint32_t;
|
(*array).magic = 0xa11aai32 as uint32_t;
|
||||||
(*array).count = 0i32 as size_t;
|
(*array).count = 0i32 as size_t;
|
||||||
(*array).allocated = if initsize < 1 { 1 } else { initsize };
|
(*array).allocated = if initsize < 1 { 1 } else { initsize };
|
||||||
|
|||||||
@@ -740,7 +740,7 @@ unsafe fn prepare_msg_raw(
|
|||||||
VALUES (?,?,?, ?,?,1);\x00" as *const u8
|
VALUES (?,?,?, ?,?,1);\x00" as *const u8
|
||||||
as *const libc::c_char,
|
as *const libc::c_char,
|
||||||
);
|
);
|
||||||
sqlite3_bind_int64(stmt, 1, timestamp as libc::int64_t);
|
sqlite3_bind_int64(stmt, 1, timestamp as i64);
|
||||||
sqlite3_bind_int(stmt, 2, DC_CONTACT_ID_SELF as libc::c_int);
|
sqlite3_bind_int(stmt, 2, DC_CONTACT_ID_SELF as libc::c_int);
|
||||||
sqlite3_bind_int(stmt, 3, (*chat).id as libc::c_int);
|
sqlite3_bind_int(stmt, 3, (*chat).id as libc::c_int);
|
||||||
sqlite3_bind_double(
|
sqlite3_bind_double(
|
||||||
|
|||||||
@@ -83,15 +83,12 @@ pub unsafe fn dc_get_chatlist<'a>(
|
|||||||
pub unsafe fn dc_chatlist_new(context: &Context) -> *mut dc_chatlist_t {
|
pub unsafe fn dc_chatlist_new(context: &Context) -> *mut dc_chatlist_t {
|
||||||
let mut chatlist: *mut dc_chatlist_t;
|
let mut chatlist: *mut dc_chatlist_t;
|
||||||
chatlist = calloc(1, ::std::mem::size_of::<dc_chatlist_t>()) as *mut dc_chatlist_t;
|
chatlist = calloc(1, ::std::mem::size_of::<dc_chatlist_t>()) as *mut dc_chatlist_t;
|
||||||
if chatlist.is_null() {
|
assert!(!chatlist.is_null());
|
||||||
exit(20i32);
|
|
||||||
}
|
|
||||||
(*chatlist).magic = 0xc4a71157u32;
|
(*chatlist).magic = 0xc4a71157u32;
|
||||||
(*chatlist).context = context;
|
(*chatlist).context = context;
|
||||||
(*chatlist).chatNlastmsg_ids = dc_array_new(128i32 as size_t);
|
(*chatlist).chatNlastmsg_ids = dc_array_new(128i32 as size_t);
|
||||||
if (*chatlist).chatNlastmsg_ids.is_null() {
|
assert!(!(*chatlist).chatNlastmsg_ids.is_null());
|
||||||
exit(32i32);
|
|
||||||
}
|
|
||||||
chatlist
|
chatlist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1406,7 +1406,7 @@ unsafe fn moz_autoconfigure_text_cb(
|
|||||||
(*(*moz_ac).out).mail_server = val;
|
(*(*moz_ac).out).mail_server = val;
|
||||||
val = 0 as *mut libc::c_char
|
val = 0 as *mut libc::c_char
|
||||||
}
|
}
|
||||||
11 => (*(*moz_ac).out).mail_port = atoi(val),
|
11 => (*(*moz_ac).out).mail_port = dc_atoi_null_is_0(val),
|
||||||
12 => {
|
12 => {
|
||||||
free((*(*moz_ac).out).mail_user as *mut libc::c_void);
|
free((*(*moz_ac).out).mail_user as *mut libc::c_void);
|
||||||
(*(*moz_ac).out).mail_user = val;
|
(*(*moz_ac).out).mail_user = val;
|
||||||
@@ -1432,7 +1432,7 @@ unsafe fn moz_autoconfigure_text_cb(
|
|||||||
(*(*moz_ac).out).send_server = val;
|
(*(*moz_ac).out).send_server = val;
|
||||||
val = 0 as *mut libc::c_char
|
val = 0 as *mut libc::c_char
|
||||||
}
|
}
|
||||||
11 => (*(*moz_ac).out).send_port = atoi(val),
|
11 => (*(*moz_ac).out).send_port = to_str(val).parse().unwrap_or_default(),
|
||||||
12 => {
|
12 => {
|
||||||
free((*(*moz_ac).out).send_user as *mut libc::c_void);
|
free((*(*moz_ac).out).send_user as *mut libc::c_void);
|
||||||
(*(*moz_ac).out).send_user = val;
|
(*(*moz_ac).out).send_user = val;
|
||||||
|
|||||||
@@ -240,9 +240,8 @@ pub unsafe fn dc_block_contact(context: &Context, contact_id: uint32_t, new_bloc
|
|||||||
pub unsafe fn dc_contact_new<'a>(context: &'a Context) -> *mut dc_contact_t<'a> {
|
pub unsafe fn dc_contact_new<'a>(context: &'a Context) -> *mut dc_contact_t<'a> {
|
||||||
let mut contact: *mut dc_contact_t;
|
let mut contact: *mut dc_contact_t;
|
||||||
contact = calloc(1, ::std::mem::size_of::<dc_contact_t>()) as *mut dc_contact_t;
|
contact = calloc(1, ::std::mem::size_of::<dc_contact_t>()) as *mut dc_contact_t;
|
||||||
if contact.is_null() {
|
assert!(!contact.is_null());
|
||||||
exit(19i32);
|
|
||||||
}
|
|
||||||
(*contact).magic = 0xc047ac7i32 as uint32_t;
|
(*contact).magic = 0xc047ac7i32 as uint32_t;
|
||||||
(*contact).context = context;
|
(*contact).context = context;
|
||||||
|
|
||||||
|
|||||||
@@ -96,10 +96,10 @@ macro_rules! info {
|
|||||||
};
|
};
|
||||||
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {{
|
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {{
|
||||||
let formatted = format!($msg, $($args),*);
|
let formatted = format!($msg, $($args),*);
|
||||||
let formatted_c = crate::dc_tools::to_cstring(formatted);
|
let formatted_c = $crate::dc_tools::to_cstring(formatted);
|
||||||
unsafe {
|
unsafe {
|
||||||
($ctx.cb)($ctx, crate::constants::Event::INFO, $data1 as uintptr_t,
|
($ctx.cb)($ctx, $crate::constants::Event::INFO, $data1 as uintptr_t,
|
||||||
crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as uintptr_t)
|
$crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as uintptr_t)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
@@ -111,10 +111,10 @@ macro_rules! warn {
|
|||||||
};
|
};
|
||||||
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
|
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
|
||||||
let formatted = format!($msg, $($args),*);
|
let formatted = format!($msg, $($args),*);
|
||||||
let formatted_c = crate::dc_tools::to_cstring(formatted);
|
let formatted_c = $crate::dc_tools::to_cstring(formatted);
|
||||||
unsafe {
|
unsafe {
|
||||||
($ctx.cb)($ctx, crate::constants::Event::WARNING, $data1 as libc::uintptr_t,
|
($ctx.cb)($ctx, $crate::constants::Event::WARNING, $data1 as libc::uintptr_t,
|
||||||
crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as libc::uintptr_t)
|
$crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as libc::uintptr_t)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -126,10 +126,10 @@ macro_rules! error {
|
|||||||
};
|
};
|
||||||
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
|
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
|
||||||
let formatted = format!($msg, $($args),*);
|
let formatted = format!($msg, $($args),*);
|
||||||
let formatted_c = crate::dc_tools::to_cstring(formatted);
|
let formatted_c = $crate::dc_tools::to_cstring(formatted);
|
||||||
unsafe {
|
unsafe {
|
||||||
($ctx.cb)($ctx, crate::constants::Event::ERROR, $data1 as uintptr_t,
|
($ctx.cb)($ctx, $crate::constants::Event::ERROR, $data1 as uintptr_t,
|
||||||
crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as uintptr_t)
|
$crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as uintptr_t)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -141,10 +141,10 @@ macro_rules! log_event {
|
|||||||
};
|
};
|
||||||
($ctx:expr, $event:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
|
($ctx:expr, $event:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
|
||||||
let formatted = format!($msg, $($args),*);
|
let formatted = format!($msg, $($args),*);
|
||||||
let formatted_c = crate::dc_tools::to_cstring(formatted);
|
let formatted_c = $crate::dc_tools::to_cstring(formatted);
|
||||||
unsafe {
|
unsafe {
|
||||||
($ctx.cb)($ctx, $event, $data1 as uintptr_t,
|
($ctx.cb)($ctx, $event, $data1 as uintptr_t,
|
||||||
crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as uintptr_t)
|
$crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as uintptr_t)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ pub struct dc_loginparam_t {
|
|||||||
pub unsafe fn dc_loginparam_new() -> *mut dc_loginparam_t {
|
pub unsafe fn dc_loginparam_new() -> *mut dc_loginparam_t {
|
||||||
let loginparam: *mut dc_loginparam_t;
|
let loginparam: *mut dc_loginparam_t;
|
||||||
loginparam = calloc(1, ::std::mem::size_of::<dc_loginparam_t>()) as *mut dc_loginparam_t;
|
loginparam = calloc(1, ::std::mem::size_of::<dc_loginparam_t>()) as *mut dc_loginparam_t;
|
||||||
if loginparam.is_null() {
|
assert!(!loginparam.is_null());
|
||||||
exit(22i32);
|
|
||||||
}
|
|
||||||
|
|
||||||
loginparam
|
loginparam
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,9 +36,8 @@ pub struct dc_lot_t {
|
|||||||
pub unsafe fn dc_lot_new() -> *mut dc_lot_t {
|
pub unsafe fn dc_lot_new() -> *mut dc_lot_t {
|
||||||
let mut lot: *mut dc_lot_t;
|
let mut lot: *mut dc_lot_t;
|
||||||
lot = calloc(1, ::std::mem::size_of::<dc_lot_t>()) as *mut dc_lot_t;
|
lot = calloc(1, ::std::mem::size_of::<dc_lot_t>()) as *mut dc_lot_t;
|
||||||
if lot.is_null() {
|
assert!(!lot.is_null());
|
||||||
exit(27i32);
|
|
||||||
}
|
|
||||||
(*lot).magic = 0x107107i32 as uint32_t;
|
(*lot).magic = 0x107107i32 as uint32_t;
|
||||||
(*lot).text1_meaning = 0i32;
|
(*lot).text1_meaning = 0i32;
|
||||||
|
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ pub unsafe fn dc_mimeparser_parse(
|
|||||||
b"Chat-Duration\x00" as *const u8 as *const libc::c_char,
|
b"Chat-Duration\x00" as *const u8 as *const libc::c_char,
|
||||||
);
|
);
|
||||||
if !field_0.is_null() {
|
if !field_0.is_null() {
|
||||||
let duration_ms: libc::c_int = atoi((*field_0).fld_value);
|
let duration_ms: libc::c_int = dc_atoi_null_is_0((*field_0).fld_value);
|
||||||
if duration_ms > 0i32 && duration_ms < 24i32 * 60i32 * 60i32 * 1000i32 {
|
if duration_ms > 0i32 && duration_ms < 24i32 * 60i32 * 60i32 * 1000i32 {
|
||||||
dc_param_set_int((*part_3).param, 'd' as i32, duration_ms);
|
dc_param_set_int((*part_3).param, 'd' as i32, duration_ms);
|
||||||
}
|
}
|
||||||
@@ -439,9 +439,7 @@ pub unsafe fn dc_mimeparser_parse(
|
|||||||
unsafe fn dc_mimepart_new() -> *mut dc_mimepart_t {
|
unsafe fn dc_mimepart_new() -> *mut dc_mimepart_t {
|
||||||
let mut mimepart: *mut dc_mimepart_t;
|
let mut mimepart: *mut dc_mimepart_t;
|
||||||
mimepart = calloc(1, ::std::mem::size_of::<dc_mimepart_t>()) as *mut dc_mimepart_t;
|
mimepart = calloc(1, ::std::mem::size_of::<dc_mimepart_t>()) as *mut dc_mimepart_t;
|
||||||
if mimepart.is_null() {
|
assert!(!mimepart.is_null());
|
||||||
exit(33i32);
|
|
||||||
}
|
|
||||||
(*mimepart).type_0 = 0i32;
|
(*mimepart).type_0 = 0i32;
|
||||||
(*mimepart).param = dc_param_new();
|
(*mimepart).param = dc_param_new();
|
||||||
mimepart
|
mimepart
|
||||||
|
|||||||
@@ -302,9 +302,7 @@ pub unsafe fn dc_msg_new_untyped<'a>(context: &'a Context) -> *mut dc_msg_t<'a>
|
|||||||
pub unsafe fn dc_msg_new<'a>(context: &'a Context, viewtype: libc::c_int) -> *mut dc_msg_t<'a> {
|
pub unsafe fn dc_msg_new<'a>(context: &'a Context, viewtype: libc::c_int) -> *mut dc_msg_t<'a> {
|
||||||
let mut msg: *mut dc_msg_t;
|
let mut msg: *mut dc_msg_t;
|
||||||
msg = calloc(1, ::std::mem::size_of::<dc_msg_t>()) as *mut dc_msg_t;
|
msg = calloc(1, ::std::mem::size_of::<dc_msg_t>()) as *mut dc_msg_t;
|
||||||
if msg.is_null() {
|
assert!(!msg.is_null());
|
||||||
exit(15i32);
|
|
||||||
}
|
|
||||||
(*msg).context = context;
|
(*msg).context = context;
|
||||||
(*msg).magic = 0x11561156i32 as uint32_t;
|
(*msg).magic = 0x11561156i32 as uint32_t;
|
||||||
(*msg).type_0 = viewtype;
|
(*msg).type_0 = viewtype;
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ pub unsafe fn dc_param_get_int(
|
|||||||
if str.is_null() {
|
if str.is_null() {
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
let ret: int32_t = atol(str) as int32_t;
|
let ret: int32_t = to_str(str).parse().unwrap_or_default();
|
||||||
free(str as *mut libc::c_void);
|
free(str as *mut libc::c_void);
|
||||||
|
|
||||||
ret
|
ret
|
||||||
@@ -300,9 +300,7 @@ pub unsafe fn dc_param_set_int(param: *mut dc_param_t, key: libc::c_int, value:
|
|||||||
pub unsafe fn dc_param_new() -> *mut dc_param_t {
|
pub unsafe fn dc_param_new() -> *mut dc_param_t {
|
||||||
let mut param: *mut dc_param_t;
|
let mut param: *mut dc_param_t;
|
||||||
param = calloc(1, ::std::mem::size_of::<dc_param_t>()) as *mut dc_param_t;
|
param = calloc(1, ::std::mem::size_of::<dc_param_t>()) as *mut dc_param_t;
|
||||||
if param.is_null() {
|
assert!(!param.is_null());
|
||||||
exit(28i32);
|
|
||||||
}
|
|
||||||
(*param).packed = calloc(1, 1) as *mut libc::c_char;
|
(*param).packed = calloc(1, 1) as *mut libc::c_char;
|
||||||
|
|
||||||
param
|
param
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ pub struct dc_simplify_t {
|
|||||||
pub unsafe fn dc_simplify_new() -> *mut dc_simplify_t {
|
pub unsafe fn dc_simplify_new() -> *mut dc_simplify_t {
|
||||||
let simplify: *mut dc_simplify_t;
|
let simplify: *mut dc_simplify_t;
|
||||||
simplify = calloc(1, ::std::mem::size_of::<dc_simplify_t>()) as *mut dc_simplify_t;
|
simplify = calloc(1, ::std::mem::size_of::<dc_simplify_t>()) as *mut dc_simplify_t;
|
||||||
if simplify.is_null() {
|
assert!(!simplify.is_null());
|
||||||
exit(31i32);
|
|
||||||
}
|
|
||||||
|
|
||||||
simplify
|
simplify
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1166,7 +1166,7 @@ pub unsafe fn dc_sqlite3_get_config_int(
|
|||||||
if str.is_null() {
|
if str.is_null() {
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
let ret = atoi(str) as int32_t;
|
let ret = dc_atoi_null_is_0(str);
|
||||||
free(str as *mut libc::c_void);
|
free(str as *mut libc::c_void);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ pub unsafe fn dc_strbuilder_init(mut strbuilder: *mut dc_strbuilder_t, init_byte
|
|||||||
128i32
|
128i32
|
||||||
};
|
};
|
||||||
(*strbuilder).buf = malloc((*strbuilder).allocated as usize) as *mut libc::c_char;
|
(*strbuilder).buf = malloc((*strbuilder).allocated as usize) as *mut libc::c_char;
|
||||||
if (*strbuilder).buf.is_null() {
|
assert!(!(*strbuilder).buf.is_null());
|
||||||
exit(38i32);
|
|
||||||
}
|
|
||||||
*(*strbuilder).buf.offset(0isize) = 0i32 as libc::c_char;
|
*(*strbuilder).buf.offset(0isize) = 0i32 as libc::c_char;
|
||||||
(*strbuilder).free = (*strbuilder).allocated - 1i32;
|
(*strbuilder).free = (*strbuilder).allocated - 1i32;
|
||||||
(*strbuilder).eos = (*strbuilder).buf;
|
(*strbuilder).eos = (*strbuilder).buf;
|
||||||
@@ -47,9 +45,7 @@ pub unsafe fn dc_strbuilder_cat(
|
|||||||
(*strbuilder).buf as *mut libc::c_void,
|
(*strbuilder).buf as *mut libc::c_void,
|
||||||
((*strbuilder).allocated + add_bytes) as usize,
|
((*strbuilder).allocated + add_bytes) as usize,
|
||||||
) as *mut libc::c_char;
|
) as *mut libc::c_char;
|
||||||
if (*strbuilder).buf.is_null() {
|
assert!(!(*strbuilder).buf.is_null());
|
||||||
exit(39i32);
|
|
||||||
}
|
|
||||||
(*strbuilder).free = (*strbuilder).free + add_bytes;
|
(*strbuilder).free = (*strbuilder).free + add_bytes;
|
||||||
(*strbuilder).eos = (*strbuilder).buf.offset(old_offset as isize)
|
(*strbuilder).eos = (*strbuilder).buf.offset(old_offset as isize)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,18 +10,9 @@ use crate::types::*;
|
|||||||
use crate::x::*;
|
use crate::x::*;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn isalnum(mut _c: libc::c_int) -> libc::c_int {
|
pub fn isalnum(c: libc::c_int) -> libc::c_int {
|
||||||
if _c < std::u8::MAX as libc::c_int {
|
if c < std::u8::MAX as libc::c_int {
|
||||||
(_c as u8 as char).is_ascii_alphanumeric() as libc::c_int
|
(c as u8 as char).is_ascii_alphanumeric() as libc::c_int
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn isdigit(mut _c: libc::c_int) -> libc::c_int {
|
|
||||||
if _c < std::u8::MAX as libc::c_int {
|
|
||||||
(_c as u8 as char).is_ascii_digit() as libc::c_int
|
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
@@ -116,12 +107,16 @@ pub unsafe fn dc_urldecode(to_decode: *const libc::c_char) -> *mut libc::c_char
|
|||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn hex_2_int(ch: libc::c_char) -> libc::c_char {
|
fn hex_2_int(ch: libc::c_char) -> libc::c_char {
|
||||||
return (if 0 != isdigit(ch as libc::c_int) {
|
let ch = ch as u8 as char;
|
||||||
ch as libc::c_int - '0' as i32
|
if !ch.is_ascii_hexdigit() {
|
||||||
} else {
|
return (ch.to_ascii_lowercase() as i32 - 'a' as i32 + 10) as libc::c_char;
|
||||||
tolower(ch as libc::c_int) - 'a' as i32 + 10i32
|
}
|
||||||
}) as libc::c_char;
|
|
||||||
|
match ch.to_digit(16) {
|
||||||
|
Some(res) => res as libc::c_char,
|
||||||
|
None => 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_encode_header_words(to_encode: *const libc::c_char) -> *mut libc::c_char {
|
pub unsafe fn dc_encode_header_words(to_encode: *const libc::c_char) -> *mut libc::c_char {
|
||||||
@@ -956,4 +951,11 @@ mod tests {
|
|||||||
free(buf2 as *mut libc::c_void);
|
free(buf2 as *mut libc::c_void);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_hex_to_int() {
|
||||||
|
assert_eq!(hex_2_int(b'A' as libc::c_char), 10);
|
||||||
|
assert_eq!(hex_2_int(b'a' as libc::c_char), 10);
|
||||||
|
assert_eq!(hex_2_int(b'4' as libc::c_char), 4);
|
||||||
|
assert_eq!(hex_2_int(b'K' as libc::c_char), 20);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,14 +27,10 @@ pub unsafe fn dc_strdup(s: *const libc::c_char) -> *mut libc::c_char {
|
|||||||
let ret: *mut libc::c_char;
|
let ret: *mut libc::c_char;
|
||||||
if !s.is_null() {
|
if !s.is_null() {
|
||||||
ret = strdup(s);
|
ret = strdup(s);
|
||||||
if ret.is_null() {
|
assert!(!ret.is_null());
|
||||||
exit(16i32);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ret = calloc(1, 1) as *mut libc::c_char;
|
ret = calloc(1, 1) as *mut libc::c_char;
|
||||||
if ret.is_null() {
|
assert!(!ret.is_null());
|
||||||
exit(17i32);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
@@ -50,24 +46,19 @@ pub unsafe fn dc_strdup_keep_null(s: *const libc::c_char) -> *mut libc::c_char {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_atoi_null_is_0(s: *const libc::c_char) -> libc::c_int {
|
pub unsafe fn dc_atoi_null_is_0(s: *const libc::c_char) -> libc::c_int {
|
||||||
return if !s.is_null() { atoi(s) } else { 0i32 };
|
if !s.is_null() {
|
||||||
|
to_str(s).parse().unwrap_or_default()
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_atof(str: *const libc::c_char) -> libc::c_double {
|
pub fn dc_atof(s: *const libc::c_char) -> libc::c_double {
|
||||||
// hack around atof() that may accept only `,` as decimal point on mac
|
if s.is_null() {
|
||||||
let test: *mut libc::c_char = dc_mprintf(b"%f\x00" as *const u8 as *const libc::c_char, 1.2f64);
|
return 0.;
|
||||||
*test.offset(2isize) = 0i32 as libc::c_char;
|
}
|
||||||
let mut str_locale: *mut libc::c_char = dc_strdup(str);
|
|
||||||
dc_str_replace(
|
|
||||||
&mut str_locale,
|
|
||||||
b".\x00" as *const u8 as *const libc::c_char,
|
|
||||||
test.offset(1isize),
|
|
||||||
);
|
|
||||||
let f: libc::c_double = atof(str_locale);
|
|
||||||
free(test as *mut libc::c_void);
|
|
||||||
free(str_locale as *mut libc::c_void);
|
|
||||||
|
|
||||||
f
|
to_str(s).parse().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_str_replace(
|
pub unsafe fn dc_str_replace(
|
||||||
@@ -184,22 +175,14 @@ pub unsafe fn dc_trim(buf: *mut libc::c_char) {
|
|||||||
|
|
||||||
/* the result must be free()'d */
|
/* the result must be free()'d */
|
||||||
pub unsafe fn dc_strlower(in_0: *const libc::c_char) -> *mut libc::c_char {
|
pub unsafe fn dc_strlower(in_0: *const libc::c_char) -> *mut libc::c_char {
|
||||||
let out: *mut libc::c_char = dc_strdup(in_0);
|
let raw = to_cstring(to_string(in_0).to_lowercase());
|
||||||
let mut p: *mut libc::c_char = out;
|
strdup(raw.as_ptr())
|
||||||
while 0 != *p {
|
|
||||||
*p = tolower(*p as libc::c_int) as libc::c_char;
|
|
||||||
p = p.offset(1isize)
|
|
||||||
}
|
|
||||||
|
|
||||||
out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_strlower_in_place(in_0: *mut libc::c_char) {
|
pub unsafe fn dc_strlower_in_place(in_0: *mut libc::c_char) {
|
||||||
let mut p: *mut libc::c_char = in_0;
|
let raw = to_cstring(to_string(in_0).to_lowercase());
|
||||||
while 0 != *p {
|
assert_eq!(strlen(in_0), strlen(raw.as_ptr()));
|
||||||
*p = tolower(*p as libc::c_int) as libc::c_char;
|
memcpy(in_0 as *mut _, raw.as_ptr() as *const _, strlen(in_0));
|
||||||
p = p.offset(1isize)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_str_contains(
|
pub unsafe fn dc_str_contains(
|
||||||
@@ -231,9 +214,7 @@ pub unsafe fn dc_null_terminate(
|
|||||||
bytes: libc::c_int,
|
bytes: libc::c_int,
|
||||||
) -> *mut libc::c_char {
|
) -> *mut libc::c_char {
|
||||||
let out: *mut libc::c_char = malloc(bytes as usize + 1) as *mut libc::c_char;
|
let out: *mut libc::c_char = malloc(bytes as usize + 1) as *mut libc::c_char;
|
||||||
if out.is_null() {
|
assert!(!out.is_null());
|
||||||
exit(45i32);
|
|
||||||
}
|
|
||||||
if !in_0.is_null() && bytes > 0i32 {
|
if !in_0.is_null() && bytes > 0i32 {
|
||||||
strncpy(out, in_0, bytes as usize);
|
strncpy(out, in_0, bytes as usize);
|
||||||
}
|
}
|
||||||
@@ -566,9 +547,8 @@ pub unsafe fn dc_str_to_clist(
|
|||||||
delimiter: *const libc::c_char,
|
delimiter: *const libc::c_char,
|
||||||
) -> *mut clist {
|
) -> *mut clist {
|
||||||
let list: *mut clist = clist_new();
|
let list: *mut clist = clist_new();
|
||||||
if list.is_null() {
|
assert!(!list.is_null());
|
||||||
exit(54i32);
|
|
||||||
}
|
|
||||||
if !str.is_null() && !delimiter.is_null() && strlen(delimiter) >= 1 {
|
if !str.is_null() && !delimiter.is_null() && strlen(delimiter) >= 1 {
|
||||||
let mut p1: *const libc::c_char = str;
|
let mut p1: *const libc::c_char = str;
|
||||||
loop {
|
loop {
|
||||||
@@ -779,9 +759,8 @@ unsafe fn encode_66bits_as_base64(v1: uint32_t, v2: uint32_t, fill: uint32_t) ->
|
|||||||
hex: 64 bit, 4 bits/character, length = 64/4 = 16 characters
|
hex: 64 bit, 4 bits/character, length = 64/4 = 16 characters
|
||||||
base64: 64 bit, 6 bits/character, length = 64/6 = 11 characters (plus 2 additional bits) */
|
base64: 64 bit, 6 bits/character, length = 64/6 = 11 characters (plus 2 additional bits) */
|
||||||
let ret: *mut libc::c_char = malloc(12) as *mut libc::c_char;
|
let ret: *mut libc::c_char = malloc(12) as *mut libc::c_char;
|
||||||
if ret.is_null() {
|
assert!(!ret.is_null());
|
||||||
exit(34i32);
|
|
||||||
}
|
|
||||||
static mut chars: [libc::c_char; 65] = [
|
static mut chars: [libc::c_char; 65] = [
|
||||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
|
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
|
||||||
88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
|
88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
|
||||||
@@ -1554,11 +1533,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dc_atof() {
|
fn test_dc_atof() {
|
||||||
unsafe {
|
let f: libc::c_double = dc_atof(b"1.23\x00" as *const u8 as *const libc::c_char);
|
||||||
let f: libc::c_double = dc_atof(b"1.23\x00" as *const u8 as *const libc::c_char);
|
assert!(f > 1.22f64);
|
||||||
assert!(f > 1.22f64);
|
assert!(f < 1.24f64);
|
||||||
assert!(f < 1.24f64);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
48
src/types.rs
48
src/types.rs
@@ -5,32 +5,14 @@ pub use libsqlite3_sys::*;
|
|||||||
pub use mmime::carray::*;
|
pub use mmime::carray::*;
|
||||||
pub use mmime::clist::*;
|
pub use mmime::clist::*;
|
||||||
|
|
||||||
pub type __builtin_va_list = [__va_list_tag; 1];
|
/// Callback function that should be given to dc_context_new().
|
||||||
#[derive(Copy, Clone)]
|
///
|
||||||
#[repr(C)]
|
/// @memberof Context
|
||||||
pub struct __va_list_tag {
|
/// @param context The context object as returned by dc_context_new().
|
||||||
pub gp_offset: libc::c_uint,
|
/// @param event one of the @ref DC_EVENT constants
|
||||||
pub fp_offset: libc::c_uint,
|
/// @param data1 depends on the event parameter
|
||||||
pub overflow_arg_area: *mut libc::c_void,
|
/// @param data2 depends on the event parameter
|
||||||
pub reg_save_area: *mut libc::c_void,
|
/// @return return 0 unless stated otherwise in the event parameter documentation
|
||||||
}
|
|
||||||
pub type va_list = __builtin_va_list;
|
|
||||||
pub type __int64_t = libc::c_longlong;
|
|
||||||
pub type __darwin_ct_rune_t = libc::c_int;
|
|
||||||
pub type __darwin_wchar_t = libc::c_int;
|
|
||||||
pub type __darwin_rune_t = __darwin_wchar_t;
|
|
||||||
pub type uint64_t = libc::c_ulonglong;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback function that should be given to dc_context_new().
|
|
||||||
*
|
|
||||||
* @memberof Context
|
|
||||||
* @param context The context object as returned by dc_context_new().
|
|
||||||
* @param event one of the @ref DC_EVENT constants
|
|
||||||
* @param data1 depends on the event parameter
|
|
||||||
* @param data2 depends on the event parameter
|
|
||||||
* @return return 0 unless stated otherwise in the event parameter documentation
|
|
||||||
*/
|
|
||||||
pub type dc_callback_t =
|
pub type dc_callback_t =
|
||||||
unsafe extern "C" fn(_: &Context, _: Event, _: uintptr_t, _: uintptr_t) -> uintptr_t;
|
unsafe extern "C" fn(_: &Context, _: Event, _: uintptr_t, _: uintptr_t) -> uintptr_t;
|
||||||
|
|
||||||
@@ -56,21 +38,15 @@ pub type dc_set_config_t =
|
|||||||
pub type dc_get_config_t =
|
pub type dc_get_config_t =
|
||||||
unsafe fn(_: &Context, _: *const libc::c_char, _: *const libc::c_char) -> *mut libc::c_char;
|
unsafe fn(_: &Context, _: *const libc::c_char, _: *const libc::c_char) -> *mut libc::c_char;
|
||||||
|
|
||||||
pub type sqlite_int64 = libc::int64_t;
|
pub type sqlite_int64 = i64;
|
||||||
pub type sqlite3_int64 = sqlite_int64;
|
pub type sqlite3_int64 = sqlite_int64;
|
||||||
|
|
||||||
pub type int32_t = libc::int32_t;
|
pub type int32_t = i32;
|
||||||
pub type int64_t = libc::int64_t;
|
pub type int64_t = i64;
|
||||||
pub type uintptr_t = libc::uintptr_t;
|
pub type uintptr_t = libc::uintptr_t;
|
||||||
pub type __uint8_t = libc::uint8_t;
|
|
||||||
pub type __uint16_t = libc::uint16_t;
|
|
||||||
pub type __int32_t = libc::int32_t;
|
|
||||||
pub type __uint64_t = libc::uint64_t;
|
|
||||||
|
|
||||||
pub type size_t = libc::size_t;
|
pub type size_t = libc::size_t;
|
||||||
pub type ssize_t = libc::ssize_t;
|
pub type ssize_t = libc::ssize_t;
|
||||||
pub type uint32_t = libc::c_uint;
|
pub type uint32_t = libc::c_uint;
|
||||||
pub type uint8_t = libc::c_uchar;
|
pub type uint8_t = libc::c_uchar;
|
||||||
pub type uint16_t = libc::c_ushort;
|
pub type uint16_t = libc::c_ushort;
|
||||||
|
pub type uint64_t = u64;
|
||||||
pub type __uint32_t = libc::c_uint;
|
|
||||||
|
|||||||
34
src/x.rs
34
src/x.rs
@@ -1,11 +1,9 @@
|
|||||||
use crate::dc_strbuilder::dc_strbuilder_t;
|
use crate::dc_strbuilder::dc_strbuilder_t;
|
||||||
use crate::dc_tools::*;
|
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
pub use libc::{
|
pub use libc::{
|
||||||
atoi, calloc, exit, free, malloc, memcmp, memcpy, memmove, memset, realloc, strcat, strchr,
|
calloc, exit, free, malloc, memcmp, memcpy, memmove, memset, realloc, strcat, strchr, strcmp,
|
||||||
strcmp, strcpy, strcspn, strlen, strncmp, strncpy, strrchr, strspn, strstr, strtol, system,
|
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 {
|
pub unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char {
|
||||||
@@ -28,9 +26,14 @@ pub fn strndup(s: *const libc::c_char, n: libc::c_ulong) -> *mut libc::c_char {
|
|||||||
return std::ptr::null_mut();
|
return std::ptr::null_mut();
|
||||||
}
|
}
|
||||||
|
|
||||||
let s_r = to_str(s);
|
let end = std::cmp::min(n as usize, unsafe { strlen(s) });
|
||||||
let end = std::cmp::min(n as usize, s_r.len());
|
unsafe {
|
||||||
unsafe { strdup(to_cstring(&s_r[..end]).as_ptr()) }
|
let result = malloc(end + 1);
|
||||||
|
memcpy(result, s as *const _, end);
|
||||||
|
std::ptr::write_bytes(result.offset(end as isize), b'\x00', 1);
|
||||||
|
|
||||||
|
result as *mut _
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -43,7 +46,6 @@ extern "C" {
|
|||||||
unsafe extern "C" fn(_: *const libc::c_void, _: *const libc::c_void) -> libc::c_int,
|
unsafe extern "C" fn(_: *const libc::c_void, _: *const libc::c_void) -> libc::c_int,
|
||||||
>,
|
>,
|
||||||
);
|
);
|
||||||
pub fn atol(_: *const libc::c_char) -> libc::c_long;
|
|
||||||
pub fn vsnprintf(
|
pub fn vsnprintf(
|
||||||
_: *mut libc::c_char,
|
_: *mut libc::c_char,
|
||||||
_: libc::c_ulong,
|
_: libc::c_ulong,
|
||||||
@@ -57,14 +59,6 @@ extern "C" {
|
|||||||
pub fn dc_mprintf(format: *const libc::c_char, _: ...) -> *mut libc::c_char;
|
pub fn dc_mprintf(format: *const libc::c_char, _: ...) -> *mut libc::c_char;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
|
||||||
pub use libc::atof;
|
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
pub unsafe fn atof(nptr: *mut libc::c_char) -> libc::c_double {
|
|
||||||
libc::strtod(nptr, std::ptr::null_mut())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char) -> libc::c_int {
|
pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char) -> libc::c_int {
|
||||||
let s1 = std::ffi::CStr::from_ptr(s1)
|
let s1 = std::ffi::CStr::from_ptr(s1)
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
@@ -105,14 +99,6 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::dc_tools::to_string;
|
use crate::dc_tools::to_string;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_atox() {
|
|
||||||
unsafe {
|
|
||||||
assert_eq!(atol(b"\x00" as *const u8 as *const libc::c_char), 0);
|
|
||||||
assert_eq!(atoi(b"\x00" as *const u8 as *const libc::c_char), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_strndup() {
|
fn test_strndup() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|||||||
Reference in New Issue
Block a user