inital commit

This commit is contained in:
dignifiedquire
2019-04-26 11:57:23 +03:00
commit ff99e19972
50 changed files with 71379 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/target
**/*.rs.bk
Cargo.lock
*.db

14
Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "deltachat-core-rust"
version = "0.1.0"
authors = ["dignifiedquire <dignifiedquire@gmail.com>"]
edition = "2018"
[build-dependencies]
cc = "1.0.35"
pkg-config = "0.3"
bindgen = "0.49.0"
[dependencies]
c2rust-bitfields = "0.1.0"
libc = "0.2.51"

1
README.md Normal file
View File

@@ -0,0 +1 @@
# Delta Chat Rust

28
build.rs Normal file
View File

@@ -0,0 +1,28 @@
extern crate bindgen;
extern crate cc;
fn main() {
let mut config = cc::Build::new();
config.file("misc.h");
config.file("misc.c");
config.compile("libtools.a");
println!("cargo:rustc-link-search=native=/usr/local/opt/openssl/lib");
println!("cargo:rustc-link-lib=dylib=sasl2");
println!("cargo:rustc-link-lib=dylib=ssl");
println!("cargo:rustc-link-lib=dylib=sqlite3");
println!("cargo:rustc-link-lib=dylib=pthread");
println!("cargo:rustc-link-lib=dylib=rpgp");
println!("cargo:rustc-link-lib=dylib=etpan");
println!("cargo:rustc-link-lib=dylib=iconv");
println!("cargo:rustc-link-lib=dylib=crypto");
println!("cargo:rustc-link-lib=dylib=z");
println!("cargo:rustc-link-lib=dylib=tools");
if std::env::var("TARGET").unwrap().contains("-apple") {
println!("cargo:rustc-link-lib=framework=CoreFoundation");
println!("cargo:rustc-link-lib=framework=CoreServices");
println!("cargo:rustc-link-lib=framework=Security");
}
}

163
misc.c Normal file
View File

@@ -0,0 +1,163 @@
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "misc.h"
char* dc_strdup(const char* s) /* strdup(NULL) is undefined, save_strdup(NULL) returns an empty string in this case */
{
char* ret = NULL;
if (s) {
if ((ret=strdup(s))==NULL) {
exit(16); /* cannot allocate (little) memory, unrecoverable error */
}
}
else {
if ((ret=(char*)calloc(1, 1))==NULL) {
exit(17); /* cannot allocate little memory, unrecoverable error */
}
}
return ret;
}
char* dc_mprintf(const char* format, ...)
{
char testbuf[1];
char* buf = NULL;
int char_cnt_without_zero = 0;
va_list argp;
va_list argp_copy;
va_start(argp, format);
va_copy(argp_copy, argp);
char_cnt_without_zero = vsnprintf(testbuf, 0, format, argp);
va_end(argp);
if (char_cnt_without_zero < 0) {
va_end(argp_copy);
return dc_strdup("ErrFmt");
}
buf = malloc(char_cnt_without_zero+2 /* +1 would be enough, however, protect against off-by-one-errors */);
if (buf==NULL) {
va_end(argp_copy);
return dc_strdup("ErrMem");
}
vsnprintf(buf, char_cnt_without_zero+1, format, argp_copy);
va_end(argp_copy);
return buf;
#if 0 /* old implementation based upon sqlite3 */
char *sqlite_str, *c_string;
va_list argp;
va_start(argp, format); /* expects the last non-variable argument as the second parameter */
sqlite_str = sqlite3_vmprintf(format, argp);
va_end(argp);
if (sqlite_str==NULL) {
return dc_strdup("ErrFmt"); /* error - the result must be free()'d */
}
/* as sqlite-strings must be freed using sqlite3_free() instead of a simple free(), convert it to a normal c-string */
c_string = dc_strdup(sqlite_str); /* exists on errors */
sqlite3_free(sqlite_str);
return c_string; /* success - the result must be free()'d */
#endif /* /old implementation based upon sqlite3 */
}
/**
* Add a string to the end of the current string in a string-builder-object.
* The internal buffer is reallocated as needed.
* If reallocation fails, the program halts.
*
* @param strbuilder The object to initialze. Must be initialized with
* dc_strbuilder_init().
* @param text Null-terminated string to add to the end of the string-builder-string.
* @return Returns a pointer to the copy of the given text.
* The returned pointer is a pointer inside dc_strbuilder_t::buf and MUST NOT
* be freed. If the string-builder was empty before, the returned
* pointer is equal to dc_strbuilder_t::buf.
* If the given text is NULL, NULL is returned and the string-builder-object is not modified.
*/
char* dc_strbuilder_cat(dc_strbuilder_t* strbuilder, const char* text)
{
// this function MUST NOT call logging functions as it is used to output the log
if (strbuilder==NULL || text==NULL) {
return NULL;
}
int len = strlen(text);
if (len > strbuilder->free) {
int add_bytes = DC_MAX(len, strbuilder->allocated);
int old_offset = (int)(strbuilder->eos - strbuilder->buf);
strbuilder->allocated = strbuilder->allocated + add_bytes;
strbuilder->buf = realloc(strbuilder->buf, strbuilder->allocated+add_bytes);
if (strbuilder->buf==NULL) {
exit(39);
}
strbuilder->free = strbuilder->free + add_bytes;
strbuilder->eos = strbuilder->buf + old_offset;
}
char* ret = strbuilder->eos;
strcpy(strbuilder->eos, text);
strbuilder->eos += len;
strbuilder->free -= len;
return ret;
}
/**
* Add a formatted string to a string-builder-object.
* This function is similar to dc_strbuilder_cat() but allows the same
* formatting options as eg. printf()
*
* @param strbuilder The object to initialze. Must be initialized with
* dc_strbuilder_init().
* @param format The formatting string to add to the string-builder-object.
* This parameter may be followed by data to be inserted into the
* formatting string, see eg. printf()
* @return None.
*/
void dc_strbuilder_catf(dc_strbuilder_t* strbuilder, const char* format, ...)
{
char testbuf[1];
char* buf = NULL;
int char_cnt_without_zero = 0;
va_list argp;
va_list argp_copy;
va_start(argp, format);
va_copy(argp_copy, argp);
char_cnt_without_zero = vsnprintf(testbuf, 0, format, argp);
va_end(argp);
if (char_cnt_without_zero < 0) {
va_end(argp_copy);
dc_strbuilder_cat(strbuilder, "ErrFmt");
return;
}
buf = malloc(char_cnt_without_zero+2 /* +1 would be enough, however, protect against off-by-one-errors */);
if (buf==NULL) {
va_end(argp_copy);
dc_strbuilder_cat(strbuilder, "ErrMem");
return;
}
vsnprintf(buf, char_cnt_without_zero+1, format, argp_copy);
va_end(argp_copy);
dc_strbuilder_cat(strbuilder, buf);
free(buf);
}

23
misc.h Normal file
View File

@@ -0,0 +1,23 @@
#define DC_MAX(X, Y) (((X) > (Y))? (X) : (Y))
typedef struct _dc_strbuilder dc_strbuilder_t;
char* dc_mprintf (const char* format, ...); /* The result must be free()'d. */
char* dc_strdup(const char* s);
struct _dc_strbuilder
{
char* buf;
int allocated;
int free;
char* eos;
};
//void dc_strbuilder_init (dc_strbuilder_t*, int init_bytes);
char* dc_strbuilder_cat (dc_strbuilder_t*, const char* text);
void dc_strbuilder_catf (dc_strbuilder_t*, const char* format, ...);
//void dc_strbuilder_empty (dc_strbuilder_t*);

524
src/dc_aheader.rs Normal file
View File

@@ -0,0 +1,524 @@
use libc;
extern "C" {
#[no_mangle]
fn calloc(_: libc::c_ulong, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn exit(_: libc::c_int) -> !;
#[no_mangle]
fn strcspn(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_ulong;
#[no_mangle]
fn strspn(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_ulong;
#[no_mangle]
fn strcasecmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
// handle contacts
#[no_mangle]
fn dc_may_be_valid_addr(addr: *const libc::c_char) -> libc::c_int;
/* string tools */
#[no_mangle]
fn dc_strdup(_: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn dc_trim(_: *mut libc::c_char);
#[no_mangle]
fn dc_strbuilder_init(_: *mut dc_strbuilder_t, init_bytes: libc::c_int);
#[no_mangle]
fn dc_strbuilder_cat(_: *mut dc_strbuilder_t, text: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn dc_key_new() -> *mut dc_key_t;
#[no_mangle]
fn dc_key_unref(_: *mut dc_key_t);
#[no_mangle]
fn dc_key_set_from_base64(
_: *mut dc_key_t,
base64: *const libc::c_char,
type_0: libc::c_int,
) -> libc::c_int;
#[no_mangle]
fn dc_key_render_base64(
_: *const dc_key_t,
break_every: libc::c_int,
break_chars: *const libc::c_char,
add_checksum: libc::c_int,
) -> *mut libc::c_char;
// Working with e-mail-addresses
#[no_mangle]
fn dc_addr_cmp(addr1: *const libc::c_char, addr2: *const libc::c_char) -> libc::c_int;
#[no_mangle]
fn dc_addr_normalize(addr: *const libc::c_char) -> *mut libc::c_char;
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clistcell_s {
pub data: *mut libc::c_void,
pub previous: *mut clistcell_s,
pub next: *mut clistcell_s,
}
pub type clistcell = clistcell_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clist_s {
pub first: *mut clistcell,
pub last: *mut clistcell,
pub count: libc::c_int,
}
pub type clist = clist_s;
pub type clistiter = clistcell;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_date_time {
pub dt_day: libc::c_int,
pub dt_month: libc::c_int,
pub dt_year: libc::c_int,
pub dt_hour: libc::c_int,
pub dt_min: libc::c_int,
pub dt_sec: libc::c_int,
pub dt_zone: libc::c_int,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_mailbox_list {
pub mb_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_mailbox {
pub mb_display_name: *mut libc::c_char,
pub mb_addr_spec: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_address_list {
pub ad_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_fields {
pub fld_list: *mut clist,
}
pub type unnamed = libc::c_uint;
pub const MAILIMF_FIELD_OPTIONAL_FIELD: unnamed = 22;
pub const MAILIMF_FIELD_KEYWORDS: unnamed = 21;
pub const MAILIMF_FIELD_COMMENTS: unnamed = 20;
pub const MAILIMF_FIELD_SUBJECT: unnamed = 19;
pub const MAILIMF_FIELD_REFERENCES: unnamed = 18;
pub const MAILIMF_FIELD_IN_REPLY_TO: unnamed = 17;
pub const MAILIMF_FIELD_MESSAGE_ID: unnamed = 16;
pub const MAILIMF_FIELD_BCC: unnamed = 15;
pub const MAILIMF_FIELD_CC: unnamed = 14;
pub const MAILIMF_FIELD_TO: unnamed = 13;
pub const MAILIMF_FIELD_REPLY_TO: unnamed = 12;
pub const MAILIMF_FIELD_SENDER: unnamed = 11;
pub const MAILIMF_FIELD_FROM: unnamed = 10;
pub const MAILIMF_FIELD_ORIG_DATE: unnamed = 9;
pub const MAILIMF_FIELD_RESENT_MSG_ID: unnamed = 8;
pub const MAILIMF_FIELD_RESENT_BCC: unnamed = 7;
pub const MAILIMF_FIELD_RESENT_CC: unnamed = 6;
pub const MAILIMF_FIELD_RESENT_TO: unnamed = 5;
pub const MAILIMF_FIELD_RESENT_SENDER: unnamed = 4;
pub const MAILIMF_FIELD_RESENT_FROM: unnamed = 3;
pub const MAILIMF_FIELD_RESENT_DATE: unnamed = 2;
pub const MAILIMF_FIELD_RETURN_PATH: unnamed = 1;
pub const MAILIMF_FIELD_NONE: unnamed = 0;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_field {
pub fld_type: libc::c_int,
pub fld_data: unnamed_0,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_0 {
pub fld_return_path: *mut mailimf_return,
pub fld_resent_date: *mut mailimf_orig_date,
pub fld_resent_from: *mut mailimf_from,
pub fld_resent_sender: *mut mailimf_sender,
pub fld_resent_to: *mut mailimf_to,
pub fld_resent_cc: *mut mailimf_cc,
pub fld_resent_bcc: *mut mailimf_bcc,
pub fld_resent_msg_id: *mut mailimf_message_id,
pub fld_orig_date: *mut mailimf_orig_date,
pub fld_from: *mut mailimf_from,
pub fld_sender: *mut mailimf_sender,
pub fld_reply_to: *mut mailimf_reply_to,
pub fld_to: *mut mailimf_to,
pub fld_cc: *mut mailimf_cc,
pub fld_bcc: *mut mailimf_bcc,
pub fld_message_id: *mut mailimf_message_id,
pub fld_in_reply_to: *mut mailimf_in_reply_to,
pub fld_references: *mut mailimf_references,
pub fld_subject: *mut mailimf_subject,
pub fld_comments: *mut mailimf_comments,
pub fld_keywords: *mut mailimf_keywords,
pub fld_optional_field: *mut mailimf_optional_field,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_optional_field {
pub fld_name: *mut libc::c_char,
pub fld_value: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_keywords {
pub kw_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_comments {
pub cm_value: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_subject {
pub sbj_value: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_references {
pub mid_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_in_reply_to {
pub mid_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_message_id {
pub mid_value: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_bcc {
pub bcc_addr_list: *mut mailimf_address_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_cc {
pub cc_addr_list: *mut mailimf_address_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_to {
pub to_addr_list: *mut mailimf_address_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_reply_to {
pub rt_addr_list: *mut mailimf_address_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_sender {
pub snd_mb: *mut mailimf_mailbox,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_from {
pub frm_mb_list: *mut mailimf_mailbox_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_orig_date {
pub dt_date_time: *mut mailimf_date_time,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_return {
pub ret_path: *mut mailimf_path,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_path {
pub pt_addr_spec: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_strbuilder {
pub buf: *mut libc::c_char,
pub allocated: libc::c_int,
pub free: libc::c_int,
pub eos: *mut libc::c_char,
}
pub type dc_strbuilder_t = _dc_strbuilder;
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_key {
pub binary: *mut libc::c_void,
pub bytes: libc::c_int,
pub type_0: libc::c_int,
pub _m_heap_refcnt: libc::c_int,
}
pub type dc_key_t = _dc_key;
/* *
* @class dc_aheader_t
* Library-internal. Parse and create [Autocrypt-headers](https://autocrypt.org/en/latest/level1.html#the-autocrypt-header).
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_aheader {
pub addr: *mut libc::c_char,
pub public_key: *mut dc_key_t,
pub prefer_encrypt: libc::c_int,
}
pub type dc_aheader_t = _dc_aheader;
/* the returned pointer is ref'd and must be unref'd after usage */
#[no_mangle]
pub unsafe extern "C" fn dc_aheader_new() -> *mut dc_aheader_t {
let mut aheader: *mut dc_aheader_t = 0 as *mut dc_aheader_t;
aheader = calloc(
1i32 as libc::c_ulong,
::std::mem::size_of::<dc_aheader_t>() as libc::c_ulong,
) as *mut dc_aheader_t;
if aheader.is_null() {
exit(37i32);
}
(*aheader).public_key = dc_key_new();
return aheader;
}
#[no_mangle]
pub unsafe extern "C" fn dc_aheader_new_from_imffields(
mut wanted_from: *const libc::c_char,
mut header: *const mailimf_fields,
) -> *mut dc_aheader_t {
let mut cur: *mut clistiter = 0 as *mut clistiter;
let mut fine_header: *mut dc_aheader_t = 0 as *mut dc_aheader_t;
if wanted_from.is_null() || header.is_null() {
return 0 as *mut dc_aheader_t;
}
cur = (*(*header).fld_list).first;
while !cur.is_null() {
let mut field: *mut mailimf_field = (if !cur.is_null() {
(*cur).data
} else {
0 as *mut libc::c_void
}) as *mut mailimf_field;
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int {
let mut optional_field: *mut mailimf_optional_field =
(*field).fld_data.fld_optional_field;
if !optional_field.is_null()
&& !(*optional_field).fld_name.is_null()
&& strcasecmp(
(*optional_field).fld_name,
b"Autocrypt\x00" as *const u8 as *const libc::c_char,
) == 0i32
{
let mut test: *mut dc_aheader_t = dc_aheader_new();
if 0 == dc_aheader_set_from_string(test, (*optional_field).fld_value)
|| dc_addr_cmp((*test).addr, wanted_from) != 0i32
{
dc_aheader_unref(test);
test = 0 as *mut dc_aheader_t
}
if fine_header.is_null() {
fine_header = test
} else if !test.is_null() {
dc_aheader_unref(fine_header);
dc_aheader_unref(test);
return 0 as *mut dc_aheader_t;
}
}
}
cur = if !cur.is_null() {
(*cur).next
} else {
0 as *mut clistcell_s
}
}
return fine_header;
}
#[no_mangle]
pub unsafe extern "C" fn dc_aheader_unref(mut aheader: *mut dc_aheader_t) {
if aheader.is_null() {
return;
}
free((*aheader).addr as *mut libc::c_void);
dc_key_unref((*aheader).public_key);
free(aheader as *mut libc::c_void);
}
#[no_mangle]
pub unsafe extern "C" fn dc_aheader_set_from_string(
mut aheader: *mut dc_aheader_t,
mut header_str__: *const libc::c_char,
) -> libc::c_int {
let mut current_block: u64;
/* according to RFC 5322 (Internet Message Format), the given string may contain `\r\n` before any whitespace.
we can ignore this issue as
(a) no key or value is expected to contain spaces,
(b) for the key, non-base64-characters are ignored and
(c) for parsing, we ignore `\r\n` as well as tabs for spaces */
let mut header_str: *mut libc::c_char = 0 as *mut libc::c_char;
let mut p: *mut libc::c_char = 0 as *mut libc::c_char;
let mut beg_attr_name: *mut libc::c_char = 0 as *mut libc::c_char;
let mut after_attr_name: *mut libc::c_char = 0 as *mut libc::c_char;
let mut beg_attr_value: *mut libc::c_char = 0 as *mut libc::c_char;
let mut success: libc::c_int = 0i32;
dc_aheader_empty(aheader);
if !(aheader.is_null() || header_str__.is_null()) {
(*aheader).prefer_encrypt = 0i32;
header_str = dc_strdup(header_str__);
p = header_str;
loop {
if !(0 != *p) {
current_block = 5689316957504528238;
break;
}
p = p.offset(strspn(p, b"\t\r\n =;\x00" as *const u8 as *const libc::c_char) as isize);
beg_attr_name = p;
beg_attr_value = 0 as *mut libc::c_char;
p = p.offset(strcspn(p, b"\t\r\n =;\x00" as *const u8 as *const libc::c_char) as isize);
if !(p != beg_attr_name) {
continue;
}
after_attr_name = p;
p = p.offset(strspn(p, b"\t\r\n \x00" as *const u8 as *const libc::c_char) as isize);
if *p as libc::c_int == '=' as i32 {
p = p.offset(
strspn(p, b"\t\r\n =\x00" as *const u8 as *const libc::c_char) as isize,
);
beg_attr_value = p;
p = p.offset(strcspn(p, b";\x00" as *const u8 as *const libc::c_char) as isize);
if *p as libc::c_int != '\u{0}' as i32 {
*p = '\u{0}' as i32 as libc::c_char;
p = p.offset(1isize)
}
dc_trim(beg_attr_value);
} else {
p = p
.offset(strspn(p, b"\t\r\n ;\x00" as *const u8 as *const libc::c_char) as isize)
}
*after_attr_name = '\u{0}' as i32 as libc::c_char;
if !(0 == add_attribute(aheader, beg_attr_name, beg_attr_value)) {
continue;
}
/* a bad attribute makes the whole header invalid */
current_block = 9271062167157603455;
break;
}
match current_block {
9271062167157603455 => {}
_ => {
if !(*aheader).addr.is_null() && !(*(*aheader).public_key).binary.is_null() {
success = 1i32
}
}
}
}
free(header_str as *mut libc::c_void);
if 0 == success {
dc_aheader_empty(aheader);
}
return success;
}
#[no_mangle]
pub unsafe extern "C" fn dc_aheader_empty(mut aheader: *mut dc_aheader_t) {
if aheader.is_null() {
return;
}
(*aheader).prefer_encrypt = 0i32;
free((*aheader).addr as *mut libc::c_void);
(*aheader).addr = 0 as *mut libc::c_char;
if !(*(*aheader).public_key).binary.is_null() {
dc_key_unref((*aheader).public_key);
(*aheader).public_key = dc_key_new()
};
}
/* ******************************************************************************
* Parse Autocrypt Header
******************************************************************************/
unsafe extern "C" fn add_attribute(
mut aheader: *mut dc_aheader_t,
mut name: *const libc::c_char,
mut value: *const libc::c_char,
) -> libc::c_int {
if strcasecmp(name, b"addr\x00" as *const u8 as *const libc::c_char) == 0i32 {
if value.is_null() || 0 == dc_may_be_valid_addr(value) || !(*aheader).addr.is_null() {
return 0i32;
}
(*aheader).addr = dc_addr_normalize(value);
return 1i32;
} else {
if strcasecmp(
name,
b"prefer-encrypt\x00" as *const u8 as *const libc::c_char,
) == 0i32
{
if !value.is_null()
&& strcasecmp(value, b"mutual\x00" as *const u8 as *const libc::c_char) == 0i32
{
(*aheader).prefer_encrypt = 1i32;
return 1i32;
}
return 1i32;
} else {
if strcasecmp(name, b"keydata\x00" as *const u8 as *const libc::c_char) == 0i32 {
if value.is_null()
|| !(*(*aheader).public_key).binary.is_null()
|| 0 != (*(*aheader).public_key).bytes
{
return 0i32;
}
return dc_key_set_from_base64((*aheader).public_key, value, 0i32);
} else {
if *name.offset(0isize) as libc::c_int == '_' as i32 {
return 1i32;
}
}
}
}
return 0i32;
}
#[no_mangle]
pub unsafe extern "C" fn dc_aheader_render(mut aheader: *const dc_aheader_t) -> *mut libc::c_char {
let mut success: libc::c_int = 0i32;
let mut keybase64_wrapped: *mut libc::c_char = 0 as *mut libc::c_char;
let mut ret: dc_strbuilder_t = _dc_strbuilder {
buf: 0 as *mut libc::c_char,
allocated: 0,
free: 0,
eos: 0 as *mut libc::c_char,
};
dc_strbuilder_init(&mut ret, 0i32);
if !(aheader.is_null()
|| (*aheader).addr.is_null()
|| (*(*aheader).public_key).binary.is_null()
|| (*(*aheader).public_key).type_0 != 0i32)
{
dc_strbuilder_cat(&mut ret, b"addr=\x00" as *const u8 as *const libc::c_char);
dc_strbuilder_cat(&mut ret, (*aheader).addr);
dc_strbuilder_cat(&mut ret, b"; \x00" as *const u8 as *const libc::c_char);
if (*aheader).prefer_encrypt == 1i32 {
dc_strbuilder_cat(
&mut ret,
b"prefer-encrypt=mutual; \x00" as *const u8 as *const libc::c_char,
);
}
dc_strbuilder_cat(
&mut ret,
b"keydata= \x00" as *const u8 as *const libc::c_char,
);
/* adds a whitespace every 78 characters, this allows libEtPan to wrap the lines according to RFC 5322
(which may insert a linebreak before every whitespace) */
keybase64_wrapped = dc_key_render_base64(
(*aheader).public_key,
78i32,
b" \x00" as *const u8 as *const libc::c_char,
0i32,
);
if !keybase64_wrapped.is_null() {
/*no checksum*/
dc_strbuilder_cat(&mut ret, keybase64_wrapped);
success = 1i32
}
}
if 0 == success {
free(ret.buf as *mut libc::c_void);
ret.buf = 0 as *mut libc::c_char
}
free(keybase64_wrapped as *mut libc::c_void);
return ret.buf;
}

1428
src/dc_apeerstate.rs Normal file

File diff suppressed because it is too large Load Diff

1241
src/dc_array.rs Normal file

File diff suppressed because it is too large Load Diff

3697
src/dc_chat.rs Normal file

File diff suppressed because it is too large Load Diff

1358
src/dc_chatlist.rs Normal file

File diff suppressed because it is too large Load Diff

3154
src/dc_configure.rs Normal file

File diff suppressed because it is too large Load Diff

2241
src/dc_contact.rs Normal file

File diff suppressed because it is too large Load Diff

1958
src/dc_context.rs Normal file

File diff suppressed because it is too large Load Diff

269
src/dc_dehtml.rs Normal file
View File

@@ -0,0 +1,269 @@
use libc;
extern "C" {
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
#[no_mangle]
fn strlen(_: *const libc::c_char) -> libc::c_ulong;
/* string tools */
#[no_mangle]
fn dc_strdup(_: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn dc_strdup_keep_null(_: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn dc_trim(_: *mut libc::c_char);
#[no_mangle]
fn dc_strbuilder_init(_: *mut dc_strbuilder_t, init_bytes: libc::c_int);
#[no_mangle]
fn dc_strbuilder_cat(_: *mut dc_strbuilder_t, text: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn dc_saxparser_parse(_: *mut dc_saxparser_t, text: *const libc::c_char);
#[no_mangle]
fn dc_saxparser_set_text_handler(_: *mut dc_saxparser_t, _: dc_saxparser_text_cb_t);
#[no_mangle]
fn dc_attr_find(attr: *mut *mut libc::c_char, key: *const libc::c_char) -> *const libc::c_char;
#[no_mangle]
fn dc_saxparser_set_tag_handler(
_: *mut dc_saxparser_t,
_: dc_saxparser_starttag_cb_t,
_: dc_saxparser_endtag_cb_t,
);
#[no_mangle]
fn dc_saxparser_init(_: *mut dc_saxparser_t, userData: *mut libc::c_void);
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_strbuilder {
pub buf: *mut libc::c_char,
pub allocated: libc::c_int,
pub free: libc::c_int,
pub eos: *mut libc::c_char,
}
pub type dc_strbuilder_t = _dc_strbuilder;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct dehtml_t {
pub strbuilder: dc_strbuilder_t,
pub add_text: libc::c_int,
pub last_href: *mut libc::c_char,
}
pub type dc_saxparser_t = _dc_saxparser;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_saxparser {
pub starttag_cb: dc_saxparser_starttag_cb_t,
pub endtag_cb: dc_saxparser_endtag_cb_t,
pub text_cb: dc_saxparser_text_cb_t,
pub userdata: *mut libc::c_void,
}
/* len is only informational, text is already null-terminated */
pub type dc_saxparser_text_cb_t = Option<
unsafe extern "C" fn(_: *mut libc::c_void, _: *const libc::c_char, _: libc::c_int) -> (),
>;
pub type dc_saxparser_endtag_cb_t =
Option<unsafe extern "C" fn(_: *mut libc::c_void, _: *const libc::c_char) -> ()>;
pub type dc_saxparser_starttag_cb_t = Option<
unsafe extern "C" fn(
_: *mut libc::c_void,
_: *const libc::c_char,
_: *mut *mut libc::c_char,
) -> (),
>;
/* ** library-internal *********************************************************/
/* dc_dehtml() returns way too many lineends; however, an optimisation on this issue is not needed as the lineends are typically remove in further processing by the caller */
#[no_mangle]
pub unsafe extern "C" fn dc_dehtml(mut buf_terminated: *mut libc::c_char) -> *mut libc::c_char {
dc_trim(buf_terminated);
if *buf_terminated.offset(0isize) as libc::c_int == 0i32 {
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
} else {
let mut dehtml: dehtml_t = dehtml_t {
strbuilder: _dc_strbuilder {
buf: 0 as *mut libc::c_char,
allocated: 0,
free: 0,
eos: 0 as *mut libc::c_char,
},
add_text: 0,
last_href: 0 as *mut libc::c_char,
};
let mut saxparser: dc_saxparser_t = _dc_saxparser {
starttag_cb: None,
endtag_cb: None,
text_cb: None,
userdata: 0 as *mut libc::c_void,
};
memset(
&mut dehtml as *mut dehtml_t as *mut libc::c_void,
0i32,
::std::mem::size_of::<dehtml_t>() as libc::c_ulong,
);
dehtml.add_text = 1i32;
dc_strbuilder_init(
&mut dehtml.strbuilder,
strlen(buf_terminated) as libc::c_int,
);
dc_saxparser_init(
&mut saxparser,
&mut dehtml as *mut dehtml_t as *mut libc::c_void,
);
dc_saxparser_set_tag_handler(
&mut saxparser,
Some(dehtml_starttag_cb),
Some(dehtml_endtag_cb),
);
dc_saxparser_set_text_handler(&mut saxparser, Some(dehtml_text_cb));
dc_saxparser_parse(&mut saxparser, buf_terminated);
free(dehtml.last_href as *mut libc::c_void);
return dehtml.strbuilder.buf;
};
}
unsafe extern "C" fn dehtml_text_cb(
mut userdata: *mut libc::c_void,
mut text: *const libc::c_char,
mut len: libc::c_int,
) {
let mut dehtml: *mut dehtml_t = userdata as *mut dehtml_t;
if (*dehtml).add_text != 0i32 {
let mut last_added: *mut libc::c_char = dc_strbuilder_cat(&mut (*dehtml).strbuilder, text);
if (*dehtml).add_text == 1i32 {
let mut p: *mut libc::c_uchar = last_added as *mut libc::c_uchar;
while 0 != *p {
if *p as libc::c_int == '\n' as i32 {
let mut last_is_lineend: libc::c_int = 1i32;
let mut p2: *const libc::c_uchar = p.offset(-1isize);
while p2 >= (*dehtml).strbuilder.buf as *const libc::c_uchar {
if *p2 as libc::c_int == '\r' as i32 {
p2 = p2.offset(-1isize)
} else {
if *p2 as libc::c_int == '\n' as i32 {
break;
}
last_is_lineend = 0i32;
break;
}
}
*p = (if 0 != last_is_lineend {
'\r' as i32
} else {
' ' as i32
}) as libc::c_uchar
}
p = p.offset(1isize)
}
}
};
}
unsafe extern "C" fn dehtml_endtag_cb(
mut userdata: *mut libc::c_void,
mut tag: *const libc::c_char,
) {
let mut dehtml: *mut dehtml_t = userdata as *mut dehtml_t;
if strcmp(tag, b"p\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"div\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"table\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"td\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"style\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"script\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"title\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"pre\x00" as *const u8 as *const libc::c_char) == 0i32
{
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b"\n\n\x00" as *const u8 as *const libc::c_char,
);
(*dehtml).add_text = 1i32
} else if strcmp(tag, b"a\x00" as *const u8 as *const libc::c_char) == 0i32 {
if !(*dehtml).last_href.is_null() {
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b"](\x00" as *const u8 as *const libc::c_char,
);
dc_strbuilder_cat(&mut (*dehtml).strbuilder, (*dehtml).last_href);
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b")\x00" as *const u8 as *const libc::c_char,
);
free((*dehtml).last_href as *mut libc::c_void);
(*dehtml).last_href = 0 as *mut libc::c_char
}
} else if strcmp(tag, b"b\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"strong\x00" as *const u8 as *const libc::c_char) == 0i32
{
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b"*\x00" as *const u8 as *const libc::c_char,
);
} else if strcmp(tag, b"i\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"em\x00" as *const u8 as *const libc::c_char) == 0i32
{
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b"_\x00" as *const u8 as *const libc::c_char,
);
};
}
unsafe extern "C" fn dehtml_starttag_cb(
mut userdata: *mut libc::c_void,
mut tag: *const libc::c_char,
mut attr: *mut *mut libc::c_char,
) {
let mut dehtml: *mut dehtml_t = userdata as *mut dehtml_t;
if strcmp(tag, b"p\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"div\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"table\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"td\x00" as *const u8 as *const libc::c_char) == 0i32
{
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b"\n\n\x00" as *const u8 as *const libc::c_char,
);
(*dehtml).add_text = 1i32
} else if strcmp(tag, b"br\x00" as *const u8 as *const libc::c_char) == 0i32 {
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b"\n\x00" as *const u8 as *const libc::c_char,
);
(*dehtml).add_text = 1i32
} else if strcmp(tag, b"style\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"script\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"title\x00" as *const u8 as *const libc::c_char) == 0i32
{
(*dehtml).add_text = 0i32
} else if strcmp(tag, b"pre\x00" as *const u8 as *const libc::c_char) == 0i32 {
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b"\n\n\x00" as *const u8 as *const libc::c_char,
);
(*dehtml).add_text = 2i32
} else if strcmp(tag, b"a\x00" as *const u8 as *const libc::c_char) == 0i32 {
free((*dehtml).last_href as *mut libc::c_void);
(*dehtml).last_href = dc_strdup_keep_null(dc_attr_find(
attr,
b"href\x00" as *const u8 as *const libc::c_char,
));
if !(*dehtml).last_href.is_null() {
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b"[\x00" as *const u8 as *const libc::c_char,
);
}
} else if strcmp(tag, b"b\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"strong\x00" as *const u8 as *const libc::c_char) == 0i32
{
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b"*\x00" as *const u8 as *const libc::c_char,
);
} else if strcmp(tag, b"i\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(tag, b"em\x00" as *const u8 as *const libc::c_char) == 0i32
{
dc_strbuilder_cat(
&mut (*dehtml).strbuilder,
b"_\x00" as *const u8 as *const libc::c_char,
);
};
}

2908
src/dc_e2ee.rs Normal file

File diff suppressed because it is too large Load Diff

916
src/dc_hash.rs Normal file
View File

@@ -0,0 +1,916 @@
use libc;
extern "C" {
#[no_mangle]
fn __assert_rtn(
_: *const libc::c_char,
_: *const libc::c_char,
_: libc::c_int,
_: *const libc::c_char,
) -> !;
#[no_mangle]
fn malloc(_: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn memcmp(_: *const libc::c_void, _: *const libc::c_void, _: libc::c_ulong) -> libc::c_int;
#[no_mangle]
fn memcpy(_: *mut libc::c_void, _: *const libc::c_void, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn strlen(_: *const libc::c_char) -> libc::c_ulong;
}
pub type uintptr_t = libc::c_ulong;
/* A complete hash table is an instance of the following structure.
* The internals of this structure are intended to be opaque -- client
* code should not attempt to access or modify the fields of this structure
* directly. Change this structure only by using the routines below.
* However, many of the "procedures" and "functions" for modifying and
* accessing this structure are really macros, so we can't really make
* this structure opaque.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_hash {
pub keyClass: libc::c_char,
pub copyKey: libc::c_char,
pub count: libc::c_int,
pub first: *mut dc_hashelem_t,
pub htsize: libc::c_int,
pub ht: *mut _ht,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _ht {
pub count: libc::c_int,
pub chain: *mut dc_hashelem_t,
}
pub type dc_hashelem_t = _dc_hashelem;
/* Each element in the hash table is an instance of the following
* structure. All elements are stored on a single doubly-linked list.
*
* Again, this structure is intended to be opaque, but it can't really
* be opaque because it is used by macros.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_hashelem {
pub next: *mut dc_hashelem_t,
pub prev: *mut dc_hashelem_t,
pub data: *mut libc::c_void,
pub pKey: *mut libc::c_void,
pub nKey: libc::c_int,
}
/* Forward declarations of structures.
*/
pub type dc_hash_t = _dc_hash;
/*
* There are 4 different modes of operation for a hash table:
*
* DC_HASH_INT nKey is used as the key and pKey is ignored.
*
* DC_HASH_POINTER pKey is used as the key and nKey is ignored.
*
* DC_HASH_STRING pKey points to a string that is nKey bytes long
* (including the null-terminator, if any). Case
* is ignored in comparisons.
*
* DC_HASH_BINARY pKey points to binary data nKey bytes long.
* memcmp() is used to compare keys.
*
* A copy of the key is made for DC_HASH_STRING and DC_HASH_BINARY
* if the copyKey parameter to dc_hash_init() is 1.
*/
/*
* Just to make the last parameter of dc_hash_init() more readable.
*/
/*
* Access routines. To delete an element, insert a NULL pointer.
*/
#[no_mangle]
pub unsafe extern "C" fn dc_hash_init(
mut pNew: *mut dc_hash_t,
mut keyClass: libc::c_int,
mut copyKey: libc::c_int,
) {
if 0 != pNew.is_null() as libc::c_int as libc::c_long {
__assert_rtn(
(*::std::mem::transmute::<&[u8; 13], &[libc::c_char; 13]>(b"dc_hash_init\x00"))
.as_ptr(),
b"../src/dc_hash.c\x00" as *const u8 as *const libc::c_char,
93i32,
b"pNew!=0\x00" as *const u8 as *const libc::c_char,
);
} else {
};
if 0 != !(keyClass >= 1i32 && keyClass <= 4i32) as libc::c_int as libc::c_long {
__assert_rtn(
(*::std::mem::transmute::<&[u8; 13], &[libc::c_char; 13]>(b"dc_hash_init\x00"))
.as_ptr(),
b"../src/dc_hash.c\x00" as *const u8 as *const libc::c_char,
94i32,
b"keyClass>=DC_HASH_INT && keyClass<=DC_HASH_BINARY\x00" as *const u8
as *const libc::c_char,
);
} else {
};
(*pNew).keyClass = keyClass as libc::c_char;
if keyClass == 2i32 || keyClass == 1i32 {
copyKey = 0i32
}
(*pNew).copyKey = copyKey as libc::c_char;
(*pNew).first = 0 as *mut dc_hashelem_t;
(*pNew).count = 0i32;
(*pNew).htsize = 0i32;
(*pNew).ht = 0 as *mut _ht;
}
#[no_mangle]
pub unsafe extern "C" fn dc_hash_insert(
mut pH: *mut dc_hash_t,
mut pKey: *const libc::c_void,
mut nKey: libc::c_int,
mut data: *mut libc::c_void,
) -> *mut libc::c_void {
/* Raw hash value of the key */
let mut hraw: libc::c_int = 0;
/* the hash of the key modulo hash table size */
let mut h: libc::c_int = 0;
/* Used to loop thru the element list */
let mut elem: *mut dc_hashelem_t = 0 as *mut dc_hashelem_t;
/* New element added to the pH */
let mut new_elem: *mut dc_hashelem_t = 0 as *mut dc_hashelem_t;
/* The hash function */
let mut xHash: Option<
unsafe extern "C" fn(_: *const libc::c_void, _: libc::c_int) -> libc::c_int,
> = None;
if 0 != pH.is_null() as libc::c_int as libc::c_long {
__assert_rtn(
(*::std::mem::transmute::<&[u8; 15], &[libc::c_char; 15]>(b"dc_hash_insert\x00"))
.as_ptr(),
b"../src/dc_hash.c\x00" as *const u8 as *const libc::c_char,
429i32,
b"pH!=0\x00" as *const u8 as *const libc::c_char,
);
} else {
};
xHash = hashFunction((*pH).keyClass as libc::c_int);
if 0 != xHash.is_none() as libc::c_int as libc::c_long {
__assert_rtn(
(*::std::mem::transmute::<&[u8; 15], &[libc::c_char; 15]>(b"dc_hash_insert\x00"))
.as_ptr(),
b"../src/dc_hash.c\x00" as *const u8 as *const libc::c_char,
431i32,
b"xHash!=0\x00" as *const u8 as *const libc::c_char,
);
} else {
};
hraw = xHash.expect("non-null function pointer")(pKey, nKey);
if 0 != !((*pH).htsize & (*pH).htsize - 1i32 == 0i32) as libc::c_int as libc::c_long {
__assert_rtn(
(*::std::mem::transmute::<&[u8; 15], &[libc::c_char; 15]>(b"dc_hash_insert\x00"))
.as_ptr(),
b"../src/dc_hash.c\x00" as *const u8 as *const libc::c_char,
433i32,
b"(pH->htsize & (pH->htsize-1))==0\x00" as *const u8 as *const libc::c_char,
);
} else {
};
h = hraw & (*pH).htsize - 1i32;
elem = findElementGivenHash(pH, pKey, nKey, h);
if !elem.is_null() {
let mut old_data: *mut libc::c_void = (*elem).data;
if data.is_null() {
removeElementGivenHash(pH, elem, h);
} else {
(*elem).data = data
}
return old_data;
}
if data.is_null() {
return 0 as *mut libc::c_void;
}
new_elem = sjhashMalloc(::std::mem::size_of::<dc_hashelem_t>() as libc::c_ulong as libc::c_long)
as *mut dc_hashelem_t;
if new_elem.is_null() {
return data;
}
if 0 != (*pH).copyKey as libc::c_int && !pKey.is_null() {
(*new_elem).pKey = malloc(nKey as libc::c_ulong);
if (*new_elem).pKey.is_null() {
free(new_elem as *mut libc::c_void);
return data;
}
memcpy(
(*new_elem).pKey as *mut libc::c_void,
pKey,
nKey as libc::c_ulong,
);
} else {
(*new_elem).pKey = pKey as *mut libc::c_void
}
(*new_elem).nKey = nKey;
(*pH).count += 1;
if (*pH).htsize == 0i32 {
rehash(pH, 8i32);
if (*pH).htsize == 0i32 {
(*pH).count = 0i32;
free(new_elem as *mut libc::c_void);
return data;
}
}
if (*pH).count > (*pH).htsize {
rehash(pH, (*pH).htsize * 2i32);
}
if 0 != !((*pH).htsize > 0i32) as libc::c_int as libc::c_long {
__assert_rtn(
(*::std::mem::transmute::<&[u8; 15], &[libc::c_char; 15]>(b"dc_hash_insert\x00"))
.as_ptr(),
b"../src/dc_hash.c\x00" as *const u8 as *const libc::c_char,
491i32,
b"pH->htsize>0\x00" as *const u8 as *const libc::c_char,
);
} else {
};
if 0 != !((*pH).htsize & (*pH).htsize - 1i32 == 0i32) as libc::c_int as libc::c_long {
__assert_rtn(
(*::std::mem::transmute::<&[u8; 15], &[libc::c_char; 15]>(b"dc_hash_insert\x00"))
.as_ptr(),
b"../src/dc_hash.c\x00" as *const u8 as *const libc::c_char,
492i32,
b"(pH->htsize & (pH->htsize-1))==0\x00" as *const u8 as *const libc::c_char,
);
} else {
};
h = hraw & (*pH).htsize - 1i32;
insertElement(pH, &mut *(*pH).ht.offset(h as isize), new_elem);
(*new_elem).data = data;
return 0 as *mut libc::c_void;
}
/* Link an element into the hash table
*/
unsafe extern "C" fn insertElement(
mut pH: *mut dc_hash_t,
mut pEntry: *mut _ht,
mut pNew: *mut dc_hashelem_t,
) {
/* First element already in pEntry */
let mut pHead: *mut dc_hashelem_t = 0 as *mut dc_hashelem_t;
pHead = (*pEntry).chain;
if !pHead.is_null() {
(*pNew).next = pHead;
(*pNew).prev = (*pHead).prev;
if !(*pHead).prev.is_null() {
(*(*pHead).prev).next = pNew
} else {
(*pH).first = pNew
}
(*pHead).prev = pNew
} else {
(*pNew).next = (*pH).first;
if !(*pH).first.is_null() {
(*(*pH).first).prev = pNew
}
(*pNew).prev = 0 as *mut dc_hashelem_t;
(*pH).first = pNew
}
(*pEntry).count += 1;
(*pEntry).chain = pNew;
}
/* Resize the hash table so that it cantains "new_size" buckets.
* "new_size" must be a power of 2. The hash table might fail
* to resize if sjhashMalloc() fails.
*/
unsafe extern "C" fn rehash(mut pH: *mut dc_hash_t, mut new_size: libc::c_int) {
/* The new hash table */
let mut new_ht: *mut _ht = 0 as *mut _ht;
/* For looping over existing elements */
let mut elem: *mut dc_hashelem_t = 0 as *mut dc_hashelem_t;
let mut next_elem: *mut dc_hashelem_t = 0 as *mut dc_hashelem_t;
/* The hash function */
let mut xHash: Option<
unsafe extern "C" fn(_: *const libc::c_void, _: libc::c_int) -> libc::c_int,
> = None;
if 0 != !(new_size & new_size - 1i32 == 0i32) as libc::c_int as libc::c_long {
__assert_rtn(
(*::std::mem::transmute::<&[u8; 7], &[libc::c_char; 7]>(b"rehash\x00")).as_ptr(),
b"../src/dc_hash.c\x00" as *const u8 as *const libc::c_char,
287i32,
b"(new_size & (new_size-1))==0\x00" as *const u8 as *const libc::c_char,
);
} else {
};
new_ht = sjhashMalloc(
(new_size as libc::c_ulong).wrapping_mul(::std::mem::size_of::<_ht>() as libc::c_ulong)
as libc::c_long,
) as *mut _ht;
if new_ht.is_null() {
return;
}
if !(*pH).ht.is_null() {
free((*pH).ht as *mut libc::c_void);
}
(*pH).ht = new_ht;
(*pH).htsize = new_size;
xHash = hashFunction((*pH).keyClass as libc::c_int);
elem = (*pH).first;
(*pH).first = 0 as *mut dc_hashelem_t;
while !elem.is_null() {
let mut h: libc::c_int =
xHash.expect("non-null function pointer")((*elem).pKey, (*elem).nKey) & new_size - 1i32;
next_elem = (*elem).next;
insertElement(pH, &mut *new_ht.offset(h as isize), elem);
elem = next_elem
}
}
/* Return a pointer to the appropriate hash function given the key class.
*
* About the syntax:
* The name of the function is "hashFunction". The function takes a
* single parameter "keyClass". The return value of hashFunction()
* is a pointer to another function. Specifically, the return value
* of hashFunction() is a pointer to a function that takes two parameters
* with types "const void*" and "int" and returns an "int".
*/
unsafe extern "C" fn hashFunction(
mut keyClass: libc::c_int,
) -> Option<unsafe extern "C" fn(_: *const libc::c_void, _: libc::c_int) -> libc::c_int> {
match keyClass {
1 => return Some(intHash),
2 => return Some(ptrHash),
3 => return Some(strHash),
4 => return Some(binHash),
_ => {}
}
return None;
}
/* Hash and comparison functions when the mode is SJHASH_BINARY
*/
unsafe extern "C" fn binHash(mut pKey: *const libc::c_void, mut nKey: libc::c_int) -> libc::c_int {
let mut h: libc::c_int = 0i32;
let mut z: *const libc::c_char = pKey as *const libc::c_char;
loop {
let fresh0 = nKey;
nKey = nKey - 1;
if !(fresh0 > 0i32) {
break;
}
let fresh1 = z;
z = z.offset(1);
h = h << 3i32 ^ h ^ *fresh1 as libc::c_int
}
return h & 0x7fffffffi32;
}
/* Hash and comparison functions when the mode is SJHASH_STRING
*/
unsafe extern "C" fn strHash(mut pKey: *const libc::c_void, mut nKey: libc::c_int) -> libc::c_int {
return sjhashNoCase(pKey as *const libc::c_char, nKey);
}
/* This function computes a hash on the name of a keyword.
* Case is not significant.
*/
unsafe extern "C" fn sjhashNoCase(mut z: *const libc::c_char, mut n: libc::c_int) -> libc::c_int {
let mut h: libc::c_int = 0i32;
if n <= 0i32 {
n = strlen(z) as libc::c_int
}
while n > 0i32 {
let fresh2 = z;
z = z.offset(1);
h = h << 3i32 ^ h ^ sjhashUpperToLower[*fresh2 as libc::c_uchar as usize] as libc::c_int;
n -= 1
}
return h & 0x7fffffffi32;
}
/* An array to map all upper-case characters into their corresponding
* lower-case character.
*/
static mut sjhashUpperToLower: [libc::c_uchar; 256] = [
0i32 as libc::c_uchar,
1i32 as libc::c_uchar,
2i32 as libc::c_uchar,
3i32 as libc::c_uchar,
4i32 as libc::c_uchar,
5i32 as libc::c_uchar,
6i32 as libc::c_uchar,
7i32 as libc::c_uchar,
8i32 as libc::c_uchar,
9i32 as libc::c_uchar,
10i32 as libc::c_uchar,
11i32 as libc::c_uchar,
12i32 as libc::c_uchar,
13i32 as libc::c_uchar,
14i32 as libc::c_uchar,
15i32 as libc::c_uchar,
16i32 as libc::c_uchar,
17i32 as libc::c_uchar,
18i32 as libc::c_uchar,
19i32 as libc::c_uchar,
20i32 as libc::c_uchar,
21i32 as libc::c_uchar,
22i32 as libc::c_uchar,
23i32 as libc::c_uchar,
24i32 as libc::c_uchar,
25i32 as libc::c_uchar,
26i32 as libc::c_uchar,
27i32 as libc::c_uchar,
28i32 as libc::c_uchar,
29i32 as libc::c_uchar,
30i32 as libc::c_uchar,
31i32 as libc::c_uchar,
32i32 as libc::c_uchar,
33i32 as libc::c_uchar,
34i32 as libc::c_uchar,
35i32 as libc::c_uchar,
36i32 as libc::c_uchar,
37i32 as libc::c_uchar,
38i32 as libc::c_uchar,
39i32 as libc::c_uchar,
40i32 as libc::c_uchar,
41i32 as libc::c_uchar,
42i32 as libc::c_uchar,
43i32 as libc::c_uchar,
44i32 as libc::c_uchar,
45i32 as libc::c_uchar,
46i32 as libc::c_uchar,
47i32 as libc::c_uchar,
48i32 as libc::c_uchar,
49i32 as libc::c_uchar,
50i32 as libc::c_uchar,
51i32 as libc::c_uchar,
52i32 as libc::c_uchar,
53i32 as libc::c_uchar,
54i32 as libc::c_uchar,
55i32 as libc::c_uchar,
56i32 as libc::c_uchar,
57i32 as libc::c_uchar,
58i32 as libc::c_uchar,
59i32 as libc::c_uchar,
60i32 as libc::c_uchar,
61i32 as libc::c_uchar,
62i32 as libc::c_uchar,
63i32 as libc::c_uchar,
64i32 as libc::c_uchar,
97i32 as libc::c_uchar,
98i32 as libc::c_uchar,
99i32 as libc::c_uchar,
100i32 as libc::c_uchar,
101i32 as libc::c_uchar,
102i32 as libc::c_uchar,
103i32 as libc::c_uchar,
104i32 as libc::c_uchar,
105i32 as libc::c_uchar,
106i32 as libc::c_uchar,
107i32 as libc::c_uchar,
108i32 as libc::c_uchar,
109i32 as libc::c_uchar,
110i32 as libc::c_uchar,
111i32 as libc::c_uchar,
112i32 as libc::c_uchar,
113i32 as libc::c_uchar,
114i32 as libc::c_uchar,
115i32 as libc::c_uchar,
116i32 as libc::c_uchar,
117i32 as libc::c_uchar,
118i32 as libc::c_uchar,
119i32 as libc::c_uchar,
120i32 as libc::c_uchar,
121i32 as libc::c_uchar,
122i32 as libc::c_uchar,
91i32 as libc::c_uchar,
92i32 as libc::c_uchar,
93i32 as libc::c_uchar,
94i32 as libc::c_uchar,
95i32 as libc::c_uchar,
96i32 as libc::c_uchar,
97i32 as libc::c_uchar,
98i32 as libc::c_uchar,
99i32 as libc::c_uchar,
100i32 as libc::c_uchar,
101i32 as libc::c_uchar,
102i32 as libc::c_uchar,
103i32 as libc::c_uchar,
104i32 as libc::c_uchar,
105i32 as libc::c_uchar,
106i32 as libc::c_uchar,
107i32 as libc::c_uchar,
108i32 as libc::c_uchar,
109i32 as libc::c_uchar,
110i32 as libc::c_uchar,
111i32 as libc::c_uchar,
112i32 as libc::c_uchar,
113i32 as libc::c_uchar,
114i32 as libc::c_uchar,
115i32 as libc::c_uchar,
116i32 as libc::c_uchar,
117i32 as libc::c_uchar,
118i32 as libc::c_uchar,
119i32 as libc::c_uchar,
120i32 as libc::c_uchar,
121i32 as libc::c_uchar,
122i32 as libc::c_uchar,
123i32 as libc::c_uchar,
124i32 as libc::c_uchar,
125i32 as libc::c_uchar,
126i32 as libc::c_uchar,
127i32 as libc::c_uchar,
128i32 as libc::c_uchar,
129i32 as libc::c_uchar,
130i32 as libc::c_uchar,
131i32 as libc::c_uchar,
132i32 as libc::c_uchar,
133i32 as libc::c_uchar,
134i32 as libc::c_uchar,
135i32 as libc::c_uchar,
136i32 as libc::c_uchar,
137i32 as libc::c_uchar,
138i32 as libc::c_uchar,
139i32 as libc::c_uchar,
140i32 as libc::c_uchar,
141i32 as libc::c_uchar,
142i32 as libc::c_uchar,
143i32 as libc::c_uchar,
144i32 as libc::c_uchar,
145i32 as libc::c_uchar,
146i32 as libc::c_uchar,
147i32 as libc::c_uchar,
148i32 as libc::c_uchar,
149i32 as libc::c_uchar,
150i32 as libc::c_uchar,
151i32 as libc::c_uchar,
152i32 as libc::c_uchar,
153i32 as libc::c_uchar,
154i32 as libc::c_uchar,
155i32 as libc::c_uchar,
156i32 as libc::c_uchar,
157i32 as libc::c_uchar,
158i32 as libc::c_uchar,
159i32 as libc::c_uchar,
160i32 as libc::c_uchar,
161i32 as libc::c_uchar,
162i32 as libc::c_uchar,
163i32 as libc::c_uchar,
164i32 as libc::c_uchar,
165i32 as libc::c_uchar,
166i32 as libc::c_uchar,
167i32 as libc::c_uchar,
168i32 as libc::c_uchar,
169i32 as libc::c_uchar,
170i32 as libc::c_uchar,
171i32 as libc::c_uchar,
172i32 as libc::c_uchar,
173i32 as libc::c_uchar,
174i32 as libc::c_uchar,
175i32 as libc::c_uchar,
176i32 as libc::c_uchar,
177i32 as libc::c_uchar,
178i32 as libc::c_uchar,
179i32 as libc::c_uchar,
180i32 as libc::c_uchar,
181i32 as libc::c_uchar,
182i32 as libc::c_uchar,
183i32 as libc::c_uchar,
184i32 as libc::c_uchar,
185i32 as libc::c_uchar,
186i32 as libc::c_uchar,
187i32 as libc::c_uchar,
188i32 as libc::c_uchar,
189i32 as libc::c_uchar,
190i32 as libc::c_uchar,
191i32 as libc::c_uchar,
192i32 as libc::c_uchar,
193i32 as libc::c_uchar,
194i32 as libc::c_uchar,
195i32 as libc::c_uchar,
196i32 as libc::c_uchar,
197i32 as libc::c_uchar,
198i32 as libc::c_uchar,
199i32 as libc::c_uchar,
200i32 as libc::c_uchar,
201i32 as libc::c_uchar,
202i32 as libc::c_uchar,
203i32 as libc::c_uchar,
204i32 as libc::c_uchar,
205i32 as libc::c_uchar,
206i32 as libc::c_uchar,
207i32 as libc::c_uchar,
208i32 as libc::c_uchar,
209i32 as libc::c_uchar,
210i32 as libc::c_uchar,
211i32 as libc::c_uchar,
212i32 as libc::c_uchar,
213i32 as libc::c_uchar,
214i32 as libc::c_uchar,
215i32 as libc::c_uchar,
216i32 as libc::c_uchar,
217i32 as libc::c_uchar,
218i32 as libc::c_uchar,
219i32 as libc::c_uchar,
220i32 as libc::c_uchar,
221i32 as libc::c_uchar,
222i32 as libc::c_uchar,
223i32 as libc::c_uchar,
224i32 as libc::c_uchar,
225i32 as libc::c_uchar,
226i32 as libc::c_uchar,
227i32 as libc::c_uchar,
228i32 as libc::c_uchar,
229i32 as libc::c_uchar,
230i32 as libc::c_uchar,
231i32 as libc::c_uchar,
232i32 as libc::c_uchar,
233i32 as libc::c_uchar,
234i32 as libc::c_uchar,
235i32 as libc::c_uchar,
236i32 as libc::c_uchar,
237i32 as libc::c_uchar,
238i32 as libc::c_uchar,
239i32 as libc::c_uchar,
240i32 as libc::c_uchar,
241i32 as libc::c_uchar,
242i32 as libc::c_uchar,
243i32 as libc::c_uchar,
244i32 as libc::c_uchar,
245i32 as libc::c_uchar,
246i32 as libc::c_uchar,
247i32 as libc::c_uchar,
248i32 as libc::c_uchar,
249i32 as libc::c_uchar,
250i32 as libc::c_uchar,
251i32 as libc::c_uchar,
252i32 as libc::c_uchar,
253i32 as libc::c_uchar,
254i32 as libc::c_uchar,
255i32 as libc::c_uchar,
];
/* Hash and comparison functions when the mode is SJHASH_POINTER
*/
unsafe extern "C" fn ptrHash(mut pKey: *const libc::c_void, mut nKey: libc::c_int) -> libc::c_int {
let mut x: uintptr_t = pKey as uintptr_t;
return (x ^ x << 8i32 ^ x >> 8i32) as libc::c_int;
}
/* Hash and comparison functions when the mode is SJHASH_INT
*/
unsafe extern "C" fn intHash(mut pKey: *const libc::c_void, mut nKey: libc::c_int) -> libc::c_int {
return nKey ^ nKey << 8i32 ^ nKey >> 8i32;
}
/*
** Based upon hash.c from sqlite which author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
*/
unsafe extern "C" fn sjhashMalloc(mut bytes: libc::c_long) -> *mut libc::c_void {
let mut p: *mut libc::c_void = malloc(bytes as libc::c_ulong);
if !p.is_null() {
memset(p, 0i32, bytes as libc::c_ulong);
}
return p;
}
/* Remove a single entry from the hash table given a pointer to that
* element and a hash on the element's key.
*/
unsafe extern "C" fn removeElementGivenHash(
mut pH: *mut dc_hash_t,
mut elem: *mut dc_hashelem_t,
mut h: libc::c_int,
) {
let mut pEntry: *mut _ht = 0 as *mut _ht;
if !(*elem).prev.is_null() {
(*(*elem).prev).next = (*elem).next
} else {
(*pH).first = (*elem).next
}
if !(*elem).next.is_null() {
(*(*elem).next).prev = (*elem).prev
}
pEntry = &mut *(*pH).ht.offset(h as isize) as *mut _ht;
if (*pEntry).chain == elem {
(*pEntry).chain = (*elem).next
}
(*pEntry).count -= 1;
if (*pEntry).count <= 0i32 {
(*pEntry).chain = 0 as *mut dc_hashelem_t
}
if 0 != (*pH).copyKey as libc::c_int && !(*elem).pKey.is_null() {
free((*elem).pKey);
}
free(elem as *mut libc::c_void);
(*pH).count -= 1;
}
/* This function (for internal use only) locates an element in an
* hash table that matches the given key. The hash for this key has
* already been computed and is passed as the 4th parameter.
*/
unsafe extern "C" fn findElementGivenHash(
mut pH: *const dc_hash_t,
mut pKey: *const libc::c_void,
mut nKey: libc::c_int,
mut h: libc::c_int,
) -> *mut dc_hashelem_t {
/* Used to loop thru the element list */
let mut elem: *mut dc_hashelem_t = 0 as *mut dc_hashelem_t;
/* Number of elements left to test */
let mut count: libc::c_int = 0;
/* comparison function */
let mut xCompare: Option<
unsafe extern "C" fn(
_: *const libc::c_void,
_: libc::c_int,
_: *const libc::c_void,
_: libc::c_int,
) -> libc::c_int,
> = None;
if !(*pH).ht.is_null() {
let mut pEntry: *mut _ht = &mut *(*pH).ht.offset(h as isize) as *mut _ht;
elem = (*pEntry).chain;
count = (*pEntry).count;
xCompare = compareFunction((*pH).keyClass as libc::c_int);
loop {
let fresh3 = count;
count = count - 1;
if !(0 != fresh3 && !elem.is_null()) {
break;
}
if xCompare.expect("non-null function pointer")((*elem).pKey, (*elem).nKey, pKey, nKey)
== 0i32
{
return elem;
}
elem = (*elem).next
}
}
return 0 as *mut dc_hashelem_t;
}
/* Return a pointer to the appropriate hash function given the key class.
*/
unsafe extern "C" fn compareFunction(
mut keyClass: libc::c_int,
) -> Option<
unsafe extern "C" fn(
_: *const libc::c_void,
_: libc::c_int,
_: *const libc::c_void,
_: libc::c_int,
) -> libc::c_int,
> {
match keyClass {
1 => return Some(intCompare),
2 => return Some(ptrCompare),
3 => return Some(strCompare),
4 => return Some(binCompare),
_ => {}
}
return None;
}
unsafe extern "C" fn binCompare(
mut pKey1: *const libc::c_void,
mut n1: libc::c_int,
mut pKey2: *const libc::c_void,
mut n2: libc::c_int,
) -> libc::c_int {
if n1 != n2 {
return 1i32;
}
return memcmp(pKey1, pKey2, n1 as libc::c_ulong);
}
unsafe extern "C" fn strCompare(
mut pKey1: *const libc::c_void,
mut n1: libc::c_int,
mut pKey2: *const libc::c_void,
mut n2: libc::c_int,
) -> libc::c_int {
if n1 != n2 {
return 1i32;
}
return sjhashStrNICmp(
pKey1 as *const libc::c_char,
pKey2 as *const libc::c_char,
n1,
);
}
/* Some systems have stricmp(). Others have strcasecmp(). Because
* there is no consistency, we will define our own.
*/
unsafe extern "C" fn sjhashStrNICmp(
mut zLeft: *const libc::c_char,
mut zRight: *const libc::c_char,
mut N: libc::c_int,
) -> libc::c_int {
let mut a: *mut libc::c_uchar = 0 as *mut libc::c_uchar;
let mut b: *mut libc::c_uchar = 0 as *mut libc::c_uchar;
a = zLeft as *mut libc::c_uchar;
b = zRight as *mut libc::c_uchar;
loop {
let fresh4 = N;
N = N - 1;
if !(fresh4 > 0i32
&& *a as libc::c_int != 0i32
&& sjhashUpperToLower[*a as usize] as libc::c_int
== sjhashUpperToLower[*b as usize] as libc::c_int)
{
break;
}
a = a.offset(1isize);
b = b.offset(1isize)
}
return if N < 0i32 {
0i32
} else {
sjhashUpperToLower[*a as usize] as libc::c_int
- sjhashUpperToLower[*b as usize] as libc::c_int
};
}
unsafe extern "C" fn ptrCompare(
mut pKey1: *const libc::c_void,
mut n1: libc::c_int,
mut pKey2: *const libc::c_void,
mut n2: libc::c_int,
) -> libc::c_int {
if pKey1 == pKey2 {
return 0i32;
}
if pKey1 < pKey2 {
return -1i32;
}
return 1i32;
}
unsafe extern "C" fn intCompare(
mut pKey1: *const libc::c_void,
mut n1: libc::c_int,
mut pKey2: *const libc::c_void,
mut n2: libc::c_int,
) -> libc::c_int {
return n2 - n1;
}
#[no_mangle]
pub unsafe extern "C" fn dc_hash_find(
mut pH: *const dc_hash_t,
mut pKey: *const libc::c_void,
mut nKey: libc::c_int,
) -> *mut libc::c_void {
/* A hash on key */
let mut h: libc::c_int = 0;
/* The element that matches key */
let mut elem: *mut dc_hashelem_t = 0 as *mut dc_hashelem_t;
/* The hash function */
let mut xHash: Option<
unsafe extern "C" fn(_: *const libc::c_void, _: libc::c_int) -> libc::c_int,
> = None;
if pH.is_null() || (*pH).ht.is_null() {
return 0 as *mut libc::c_void;
}
xHash = hashFunction((*pH).keyClass as libc::c_int);
if 0 != xHash.is_none() as libc::c_int as libc::c_long {
__assert_rtn(
(*::std::mem::transmute::<&[u8; 13], &[libc::c_char; 13]>(b"dc_hash_find\x00"))
.as_ptr(),
b"../src/dc_hash.c\x00" as *const u8 as *const libc::c_char,
397i32,
b"xHash!=0\x00" as *const u8 as *const libc::c_char,
);
} else {
};
h = xHash.expect("non-null function pointer")(pKey, nKey);
if 0 != !((*pH).htsize & (*pH).htsize - 1i32 == 0i32) as libc::c_int as libc::c_long {
__assert_rtn(
(*::std::mem::transmute::<&[u8; 13], &[libc::c_char; 13]>(b"dc_hash_find\x00"))
.as_ptr(),
b"../src/dc_hash.c\x00" as *const u8 as *const libc::c_char,
399i32,
b"(pH->htsize & (pH->htsize-1))==0\x00" as *const u8 as *const libc::c_char,
);
} else {
};
elem = findElementGivenHash(pH, pKey, nKey, h & (*pH).htsize - 1i32);
return if !elem.is_null() {
(*elem).data
} else {
0 as *mut libc::c_void
};
}
#[no_mangle]
pub unsafe extern "C" fn dc_hash_clear(mut pH: *mut dc_hash_t) {
/* For looping over all elements of the table */
let mut elem: *mut dc_hashelem_t = 0 as *mut dc_hashelem_t;
if pH.is_null() {
return;
}
elem = (*pH).first;
(*pH).first = 0 as *mut dc_hashelem_t;
if !(*pH).ht.is_null() {
free((*pH).ht as *mut libc::c_void);
}
(*pH).ht = 0 as *mut _ht;
(*pH).htsize = 0i32;
while !elem.is_null() {
let mut next_elem: *mut dc_hashelem_t = (*elem).next;
if 0 != (*pH).copyKey as libc::c_int && !(*elem).pKey.is_null() {
free((*elem).pKey);
}
free(elem as *mut libc::c_void);
elem = next_elem
}
(*pH).count = 0i32;
}

3290
src/dc_imap.rs Normal file

File diff suppressed because it is too large Load Diff

2816
src/dc_imex.rs Normal file

File diff suppressed because it is too large Load Diff

2652
src/dc_job.rs Normal file

File diff suppressed because it is too large Load Diff

1050
src/dc_jobthread.rs Normal file

File diff suppressed because it is too large Load Diff

398
src/dc_jsmn.rs Normal file
View File

@@ -0,0 +1,398 @@
use libc;
pub type size_t = libc::c_ulong;
/*
Copyright (c) 2010 Serge A. Zaitsev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* *
* JSON type identifier. Basic types are:
* o Object
* o Array
* o String
* o Other primitive: number, boolean (true/false) or null
*/
pub type jsmntype_t = libc::c_uint;
pub const JSMN_PRIMITIVE: jsmntype_t = 4;
pub const JSMN_STRING: jsmntype_t = 3;
pub const JSMN_ARRAY: jsmntype_t = 2;
pub const JSMN_OBJECT: jsmntype_t = 1;
pub const JSMN_UNDEFINED: jsmntype_t = 0;
pub type jsmnerr = libc::c_int;
/* The string is not a full JSON packet, more bytes expected */
pub const JSMN_ERROR_PART: jsmnerr = -3;
/* Invalid character inside JSON string */
pub const JSMN_ERROR_INVAL: jsmnerr = -2;
/* Not enough tokens were provided */
pub const JSMN_ERROR_NOMEM: jsmnerr = -1;
/* *
* JSON token description.
* type type (object, array, string etc.)
* start start position in JSON data string
* end end position in JSON data string
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct jsmntok_t {
pub type_0: jsmntype_t,
pub start: libc::c_int,
pub end: libc::c_int,
pub size: libc::c_int,
}
/* *
* JSON parser. Contains an array of token blocks available. Also stores
* the string being parsed now and current position in that string
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct jsmn_parser {
pub pos: libc::c_uint,
pub toknext: libc::c_uint,
pub toksuper: libc::c_int,
}
/* *
* Create JSON parser over an array of tokens
*/
#[no_mangle]
pub unsafe extern "C" fn jsmn_init(mut parser: *mut jsmn_parser) {
(*parser).pos = 0i32 as libc::c_uint;
(*parser).toknext = 0i32 as libc::c_uint;
(*parser).toksuper = -1i32;
}
/* *
* Run JSON parser. It parses a JSON data string into and array of tokens, each describing
* a single JSON object.
*/
#[no_mangle]
pub unsafe extern "C" fn jsmn_parse(
mut parser: *mut jsmn_parser,
mut js: *const libc::c_char,
mut len: size_t,
mut tokens: *mut jsmntok_t,
mut num_tokens: libc::c_uint,
) -> libc::c_int {
let mut r: libc::c_int = 0;
let mut i: libc::c_int = 0;
let mut token: *mut jsmntok_t = 0 as *mut jsmntok_t;
let mut count: libc::c_int = (*parser).toknext as libc::c_int;
while ((*parser).pos as libc::c_ulong) < len
&& *js.offset((*parser).pos as isize) as libc::c_int != '\u{0}' as i32
{
let mut c: libc::c_char = 0;
let mut type_0: jsmntype_t = JSMN_UNDEFINED;
c = *js.offset((*parser).pos as isize);
match c as libc::c_int {
123 | 91 => {
count += 1;
if !tokens.is_null() {
token = jsmn_alloc_token(parser, tokens, num_tokens as size_t);
if token.is_null() {
return JSMN_ERROR_NOMEM as libc::c_int;
}
if (*parser).toksuper != -1i32 {
let ref mut fresh0 = (*tokens.offset((*parser).toksuper as isize)).size;
*fresh0 += 1
}
(*token).type_0 = (if c as libc::c_int == '{' as i32 {
JSMN_OBJECT as libc::c_int
} else {
JSMN_ARRAY as libc::c_int
}) as jsmntype_t;
(*token).start = (*parser).pos as libc::c_int;
(*parser).toksuper =
(*parser).toknext.wrapping_sub(1i32 as libc::c_uint) as libc::c_int
}
}
125 | 93 => {
if !tokens.is_null() {
type_0 = (if c as libc::c_int == '}' as i32 {
JSMN_OBJECT as libc::c_int
} else {
JSMN_ARRAY as libc::c_int
}) as jsmntype_t;
i = (*parser).toknext.wrapping_sub(1i32 as libc::c_uint) as libc::c_int;
while i >= 0i32 {
token = &mut *tokens.offset(i as isize) as *mut jsmntok_t;
if (*token).start != -1i32 && (*token).end == -1i32 {
if (*token).type_0 as libc::c_uint != type_0 as libc::c_uint {
return JSMN_ERROR_INVAL as libc::c_int;
}
(*parser).toksuper = -1i32;
(*token).end =
(*parser).pos.wrapping_add(1i32 as libc::c_uint) as libc::c_int;
break;
} else {
i -= 1
}
}
if i == -1i32 {
return JSMN_ERROR_INVAL as libc::c_int;
}
while i >= 0i32 {
token = &mut *tokens.offset(i as isize) as *mut jsmntok_t;
if (*token).start != -1i32 && (*token).end == -1i32 {
(*parser).toksuper = i;
break;
} else {
i -= 1
}
}
}
}
34 => {
r = jsmn_parse_string(parser, js, len, tokens, num_tokens as size_t);
if r < 0i32 {
return r;
}
count += 1;
if (*parser).toksuper != -1i32 && !tokens.is_null() {
let ref mut fresh1 = (*tokens.offset((*parser).toksuper as isize)).size;
*fresh1 += 1
}
}
9 | 13 | 10 | 32 => {}
58 => {
(*parser).toksuper =
(*parser).toknext.wrapping_sub(1i32 as libc::c_uint) as libc::c_int
}
44 => {
if !tokens.is_null()
&& (*parser).toksuper != -1i32
&& (*tokens.offset((*parser).toksuper as isize)).type_0 as libc::c_uint
!= JSMN_ARRAY as libc::c_int as libc::c_uint
&& (*tokens.offset((*parser).toksuper as isize)).type_0 as libc::c_uint
!= JSMN_OBJECT as libc::c_int as libc::c_uint
{
i = (*parser).toknext.wrapping_sub(1i32 as libc::c_uint) as libc::c_int;
while i >= 0i32 {
if (*tokens.offset(i as isize)).type_0 as libc::c_uint
== JSMN_ARRAY as libc::c_int as libc::c_uint
|| (*tokens.offset(i as isize)).type_0 as libc::c_uint
== JSMN_OBJECT as libc::c_int as libc::c_uint
{
if (*tokens.offset(i as isize)).start != -1i32
&& (*tokens.offset(i as isize)).end == -1i32
{
(*parser).toksuper = i;
break;
}
}
i -= 1
}
}
}
_ => {
r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens as size_t);
if r < 0i32 {
return r;
}
count += 1;
if (*parser).toksuper != -1i32 && !tokens.is_null() {
let ref mut fresh2 = (*tokens.offset((*parser).toksuper as isize)).size;
*fresh2 += 1
}
}
}
(*parser).pos = (*parser).pos.wrapping_add(1)
}
if !tokens.is_null() {
i = (*parser).toknext.wrapping_sub(1i32 as libc::c_uint) as libc::c_int;
while i >= 0i32 {
if (*tokens.offset(i as isize)).start != -1i32
&& (*tokens.offset(i as isize)).end == -1i32
{
return JSMN_ERROR_PART as libc::c_int;
}
i -= 1
}
}
return count;
}
/* *
* Fills next available token with JSON primitive.
*/
unsafe extern "C" fn jsmn_parse_primitive(
mut parser: *mut jsmn_parser,
mut js: *const libc::c_char,
mut len: size_t,
mut tokens: *mut jsmntok_t,
mut num_tokens: size_t,
) -> libc::c_int {
let mut token: *mut jsmntok_t = 0 as *mut jsmntok_t;
let mut start: libc::c_int = 0;
start = (*parser).pos as libc::c_int;
while ((*parser).pos as libc::c_ulong) < len
&& *js.offset((*parser).pos as isize) as libc::c_int != '\u{0}' as i32
{
match *js.offset((*parser).pos as isize) as libc::c_int {
58 | 9 | 13 | 10 | 32 | 44 | 93 | 125 => {
break;
}
_ => {}
}
if (*js.offset((*parser).pos as isize) as libc::c_int) < 32i32
|| *js.offset((*parser).pos as isize) as libc::c_int >= 127i32
{
(*parser).pos = start as libc::c_uint;
return JSMN_ERROR_INVAL as libc::c_int;
}
(*parser).pos = (*parser).pos.wrapping_add(1)
}
if tokens.is_null() {
(*parser).pos = (*parser).pos.wrapping_sub(1);
return 0i32;
}
token = jsmn_alloc_token(parser, tokens, num_tokens);
if token.is_null() {
(*parser).pos = start as libc::c_uint;
return JSMN_ERROR_NOMEM as libc::c_int;
}
jsmn_fill_token(token, JSMN_PRIMITIVE, start, (*parser).pos as libc::c_int);
(*parser).pos = (*parser).pos.wrapping_sub(1);
return 0i32;
}
/* *
* Fills token type and boundaries.
*/
unsafe extern "C" fn jsmn_fill_token(
mut token: *mut jsmntok_t,
mut type_0: jsmntype_t,
mut start: libc::c_int,
mut end: libc::c_int,
) {
(*token).type_0 = type_0;
(*token).start = start;
(*token).end = end;
(*token).size = 0i32;
}
/*
Copyright (c) 2010 Serge A. Zaitsev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* *
* Allocates a fresh unused token from the token pool.
*/
unsafe extern "C" fn jsmn_alloc_token(
mut parser: *mut jsmn_parser,
mut tokens: *mut jsmntok_t,
mut num_tokens: size_t,
) -> *mut jsmntok_t {
let mut tok: *mut jsmntok_t = 0 as *mut jsmntok_t;
if (*parser).toknext as libc::c_ulong >= num_tokens {
return 0 as *mut jsmntok_t;
}
let fresh3 = (*parser).toknext;
(*parser).toknext = (*parser).toknext.wrapping_add(1);
tok = &mut *tokens.offset(fresh3 as isize) as *mut jsmntok_t;
(*tok).end = -1i32;
(*tok).start = (*tok).end;
(*tok).size = 0i32;
return tok;
}
/* *
* Fills next token with JSON string.
*/
unsafe extern "C" fn jsmn_parse_string(
mut parser: *mut jsmn_parser,
mut js: *const libc::c_char,
mut len: size_t,
mut tokens: *mut jsmntok_t,
mut num_tokens: size_t,
) -> libc::c_int {
let mut token: *mut jsmntok_t = 0 as *mut jsmntok_t;
let mut start: libc::c_int = (*parser).pos as libc::c_int;
(*parser).pos = (*parser).pos.wrapping_add(1);
while ((*parser).pos as libc::c_ulong) < len
&& *js.offset((*parser).pos as isize) as libc::c_int != '\u{0}' as i32
{
let mut c: libc::c_char = *js.offset((*parser).pos as isize);
if c as libc::c_int == '\"' as i32 {
if tokens.is_null() {
return 0i32;
}
token = jsmn_alloc_token(parser, tokens, num_tokens);
if token.is_null() {
(*parser).pos = start as libc::c_uint;
return JSMN_ERROR_NOMEM as libc::c_int;
}
jsmn_fill_token(
token,
JSMN_STRING,
start + 1i32,
(*parser).pos as libc::c_int,
);
return 0i32;
}
if c as libc::c_int == '\\' as i32
&& ((*parser).pos.wrapping_add(1i32 as libc::c_uint) as libc::c_ulong) < len
{
let mut i: libc::c_int = 0;
(*parser).pos = (*parser).pos.wrapping_add(1);
match *js.offset((*parser).pos as isize) as libc::c_int {
34 | 47 | 92 | 98 | 102 | 114 | 110 | 116 => {}
117 => {
(*parser).pos = (*parser).pos.wrapping_add(1);
i = 0i32;
while i < 4i32
&& ((*parser).pos as libc::c_ulong) < len
&& *js.offset((*parser).pos as isize) as libc::c_int != '\u{0}' as i32
{
if !(*js.offset((*parser).pos as isize) as libc::c_int >= 48i32
&& *js.offset((*parser).pos as isize) as libc::c_int <= 57i32
|| *js.offset((*parser).pos as isize) as libc::c_int >= 65i32
&& *js.offset((*parser).pos as isize) as libc::c_int <= 70i32
|| *js.offset((*parser).pos as isize) as libc::c_int >= 97i32
&& *js.offset((*parser).pos as isize) as libc::c_int <= 102i32)
{
(*parser).pos = start as libc::c_uint;
return JSMN_ERROR_INVAL as libc::c_int;
}
(*parser).pos = (*parser).pos.wrapping_add(1);
i += 1
}
(*parser).pos = (*parser).pos.wrapping_sub(1)
}
_ => {
(*parser).pos = start as libc::c_uint;
return JSMN_ERROR_INVAL as libc::c_int;
}
}
}
(*parser).pos = (*parser).pos.wrapping_add(1)
}
(*parser).pos = start as libc::c_uint;
return JSMN_ERROR_PART as libc::c_int;
}

1465
src/dc_key.rs Normal file

File diff suppressed because it is too large Load Diff

744
src/dc_keyhistory.rs Normal file
View File

@@ -0,0 +1,744 @@
use c2rust_bitfields::BitfieldStruct;
use libc;
extern "C" {
pub type mailstream_cancel;
pub type sqlite3;
}
pub type __darwin_size_t = libc::c_ulong;
pub type __darwin_ssize_t = libc::c_long;
pub type __darwin_time_t = libc::c_long;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_cond_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 40],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_mutex_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 56],
}
pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t;
pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t;
pub type uintptr_t = libc::c_ulong;
pub type size_t = __darwin_size_t;
pub type uint8_t = libc::c_uchar;
pub type uint32_t = libc::c_uint;
pub type ssize_t = __darwin_ssize_t;
pub type time_t = __darwin_time_t;
pub type pthread_cond_t = __darwin_pthread_cond_t;
pub type pthread_mutex_t = __darwin_pthread_mutex_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct carray_s {
pub array: *mut *mut libc::c_void,
pub len: libc::c_uint,
pub max: libc::c_uint,
}
pub type carray = carray_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream {
pub buffer_max_size: size_t,
pub write_buffer: *mut libc::c_char,
pub write_buffer_len: size_t,
pub read_buffer: *mut libc::c_char,
pub read_buffer_len: size_t,
pub low: *mut mailstream_low,
pub idle: *mut mailstream_cancel,
pub idling: libc::c_int,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
pub type mailstream = _mailstream;
pub type mailstream_low = _mailstream_low;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream_low {
pub data: *mut libc::c_void,
pub driver: *mut mailstream_low_driver,
pub privacy: libc::c_int,
pub identifier: *mut libc::c_char,
pub timeout: libc::c_ulong,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream_low,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailstream_low_driver {
pub mailstream_read: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *mut libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_write: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *const libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_close: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_get_fd: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_free: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_cancel: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_get_cancel:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut mailstream_cancel>,
pub mailstream_get_certificate_chain:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut carray>,
pub mailstream_setup_idle: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_unsetup_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_interrupt_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
}
pub type progress_function = unsafe extern "C" fn(_: size_t, _: size_t) -> ();
pub type mailprogress_function =
unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _MMAPString {
pub str_0: *mut libc::c_char,
pub len: size_t,
pub allocated_len: size_t,
pub fd: libc::c_int,
pub mmapped_size: size_t,
}
pub type MMAPString = _MMAPString;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clistcell_s {
pub data: *mut libc::c_void,
pub previous: *mut clistcell_s,
pub next: *mut clistcell_s,
}
pub type clistcell = clistcell_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clist_s {
pub first: *mut clistcell,
pub last: *mut clistcell,
pub count: libc::c_int,
}
pub type clist = clist_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailsmtp {
pub stream: *mut mailstream,
pub progr_rate: size_t,
pub progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub response: *mut libc::c_char,
pub line_buffer: *mut MMAPString,
pub response_buffer: *mut MMAPString,
pub esmtp: libc::c_int,
pub auth: libc::c_int,
pub smtp_sasl: unnamed,
pub smtp_max_msg_size: size_t,
pub smtp_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub smtp_progress_context: *mut libc::c_void,
pub response_code: libc::c_int,
pub smtp_timeout: time_t,
pub smtp_logger: Option<
unsafe extern "C" fn(
_: *mut mailsmtp,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub smtp_logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_capability_data {
pub cap_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att_body_section {
pub sec_section: *mut mailimap_section,
pub sec_origin_octet: uint32_t,
pub sec_body_part: *mut libc::c_char,
pub sec_length: size_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section {
pub sec_spec: *mut mailimap_section_spec,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_spec {
pub sec_type: libc::c_int,
pub sec_data: unnamed_0,
pub sec_text: *mut mailimap_section_text,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_text {
pub sec_type: libc::c_int,
pub sec_msgtext: *mut mailimap_section_msgtext,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_msgtext {
pub sec_type: libc::c_int,
pub sec_header_list: *mut mailimap_header_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_header_list {
pub hdr_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_0 {
pub sec_msgtext: *mut mailimap_section_msgtext,
pub sec_part: *mut mailimap_section_part,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_part {
pub sec_id: *mut clist,
}
pub type mailimap_msg_body_handler = unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_flag_list {
pub fl_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_mailbox_data_status {
pub st_mailbox: *mut libc::c_char,
pub st_info_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att {
pub att_list: *mut clist,
pub att_number: uint32_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_att {
pub att_type: libc::c_int,
pub att_section: *mut mailimap_section,
pub att_offset: uint32_t,
pub att_size: uint32_t,
pub att_extension: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_type {
pub ft_type: libc::c_int,
pub ft_data: unnamed_1,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_1 {
pub ft_fetch_att: *mut mailimap_fetch_att,
pub ft_fetch_att_list: *mut clist,
}
pub type mailimap_msg_att_handler =
unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap {
pub imap_response: *mut libc::c_char,
pub imap_stream: *mut mailstream,
pub imap_progr_rate: size_t,
pub imap_progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub imap_stream_buffer: *mut MMAPString,
pub imap_response_buffer: *mut MMAPString,
pub imap_state: libc::c_int,
pub imap_tag: libc::c_int,
pub imap_connection_info: *mut mailimap_connection_info,
pub imap_selection_info: *mut mailimap_selection_info,
pub imap_response_info: *mut mailimap_response_info,
pub imap_sasl: unnamed_2,
pub imap_idle_timestamp: time_t,
pub imap_idle_maxdelay: time_t,
pub imap_body_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_items_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_progress_context: *mut libc::c_void,
pub imap_msg_att_handler:
Option<unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ()>,
pub imap_msg_att_handler_context: *mut libc::c_void,
pub imap_msg_body_handler: Option<
unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool,
>,
pub imap_msg_body_handler_context: *mut libc::c_void,
pub imap_timeout: time_t,
pub imap_logger: Option<
unsafe extern "C" fn(
_: *mut mailimap,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub imap_logger_context: *mut libc::c_void,
pub is_163_workaround_enabled: libc::c_int,
pub is_rambler_workaround_enabled: libc::c_int,
pub is_qip_workaround_enabled: libc::c_int,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed_2 {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_response_info {
pub rsp_alert: *mut libc::c_char,
pub rsp_parse: *mut libc::c_char,
pub rsp_badcharset: *mut clist,
pub rsp_trycreate: libc::c_int,
pub rsp_mailbox_list: *mut clist,
pub rsp_mailbox_lsub: *mut clist,
pub rsp_search_result: *mut clist,
pub rsp_status: *mut mailimap_mailbox_data_status,
pub rsp_expunged: *mut clist,
pub rsp_fetch_list: *mut clist,
pub rsp_extension_list: *mut clist,
pub rsp_atom: *mut libc::c_char,
pub rsp_value: *mut libc::c_char,
}
#[derive(BitfieldStruct, Clone, Copy)]
#[repr(C)]
pub struct mailimap_selection_info {
pub sel_perm_flags: *mut clist,
pub sel_perm: libc::c_int,
pub sel_uidnext: uint32_t,
pub sel_uidvalidity: uint32_t,
pub sel_first_unseen: uint32_t,
pub sel_flags: *mut mailimap_flag_list,
pub sel_exists: uint32_t,
pub sel_recent: uint32_t,
pub sel_unseen: uint32_t,
#[bitfield(name = "sel_has_exists", ty = "uint8_t", bits = "0..=0")]
#[bitfield(name = "sel_has_recent", ty = "uint8_t", bits = "1..=1")]
pub sel_has_exists_sel_has_recent: [u8; 1],
pub _pad: [u8; 3],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_connection_info {
pub imap_capability: *mut mailimap_capability_data,
}
/* define DC_USE_RPGP to enable use of rPGP instead of netpgp where available;
preferrably, this should be done in the project configuration currently */
//#define DC_USE_RPGP 1
/* Includes that are used frequently. This file may also be used to create predefined headers. */
/* * Structure behind dc_context_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_context {
pub magic: uint32_t,
pub userdata: *mut libc::c_void,
pub dbfile: *mut libc::c_char,
pub blobdir: *mut libc::c_char,
pub sql: *mut dc_sqlite3_t,
pub inbox: *mut dc_imap_t,
pub inboxidle_condmutex: pthread_mutex_t,
pub perform_inbox_jobs_needed: libc::c_int,
pub probe_imap_network: libc::c_int,
pub sentbox_thread: dc_jobthread_t,
pub mvbox_thread: dc_jobthread_t,
pub smtp: *mut dc_smtp_t,
pub smtpidle_cond: pthread_cond_t,
pub smtpidle_condmutex: pthread_mutex_t,
pub smtpidle_condflag: libc::c_int,
pub smtp_suspended: libc::c_int,
pub smtp_doing_jobs: libc::c_int,
pub perform_smtp_jobs_needed: libc::c_int,
pub probe_smtp_network: libc::c_int,
pub oauth2_critical: pthread_mutex_t,
pub cb: dc_callback_t,
pub os_name: *mut libc::c_char,
pub cmdline_sel_chat_id: uint32_t,
pub bob_expects: libc::c_int,
pub bobs_status: libc::c_int,
pub bobs_qr_scan: *mut dc_lot_t,
pub bobs_qr_critical: pthread_mutex_t,
pub last_smeared_timestamp: time_t,
pub smear_critical: pthread_mutex_t,
pub ongoing_running: libc::c_int,
pub shall_stop_ongoing: libc::c_int,
}
pub type dc_lot_t = _dc_lot;
/* * Structure behind dc_lot_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_lot {
pub magic: uint32_t,
pub text1_meaning: libc::c_int,
pub text1: *mut libc::c_char,
pub text2: *mut libc::c_char,
pub timestamp: time_t,
pub state: libc::c_int,
pub id: uint32_t,
pub fingerprint: *mut libc::c_char,
pub invitenumber: *mut libc::c_char,
pub auth: *mut libc::c_char,
}
/* *
* Callback function that should be given to dc_context_new().
*
* @memberof dc_context_t
* @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 = Option<
unsafe extern "C" fn(
_: *mut dc_context_t,
_: libc::c_int,
_: uintptr_t,
_: uintptr_t,
) -> uintptr_t,
>;
/* *
* @mainpage Getting started
*
* This document describes how to handle the Delta Chat core library.
* For general information about Delta Chat itself,
* see <https://delta.chat> and <https://github.com/deltachat>.
*
* Let's start.
*
* First of all, you have to **define an event-handler-function**
* that is called by the library on specific events
* (eg. when the configuration is done or when fresh messages arrive).
* With this function you can create a Delta Chat context then:
*
* ~~~
* #include <deltachat.h>
*
* uintptr_t event_handler_func(dc_context_t* context, int event,
* uintptr_t data1, uintptr_t data2)
* {
* return 0; // for unhandled events, it is always safe to return 0
* }
*
* dc_context_t* context = dc_context_new(event_handler_func, NULL, NULL);
* ~~~
*
* After that, you should make sure,
* sending and receiving jobs are processed as needed.
* For this purpose, you have to **create two threads:**
*
* ~~~
* #include <pthread.h>
*
* void* imap_thread_func(void* context)
* {
* while (true) {
* dc_perform_imap_jobs(context);
* dc_perform_imap_fetch(context);
* dc_perform_imap_idle(context);
* }
* }
*
* void* smtp_thread_func(void* context)
* {
* while (true) {
* dc_perform_smtp_jobs(context);
* dc_perform_smtp_idle(context);
* }
* }
*
* static pthread_t imap_thread, smtp_thread;
* pthread_create(&imap_thread, NULL, imap_thread_func, context);
* pthread_create(&smtp_thread, NULL, smtp_thread_func, context);
* ~~~
*
* The example above uses "pthreads",
* however, you can also use anything else for thread handling.
* NB: The deltachat-core library itself does not create any threads on its own,
* however, functions, unless stated otherwise, are thread-safe.
*
* After that you can **define and open a database.**
* The database is a normal sqlite-file and is created as needed:
*
* ~~~
* dc_open(context, "example.db", NULL);
* ~~~
*
* Now you can **configure the context:**
*
* ~~~
* // use some real test credentials here
* dc_set_config(context, "addr", "alice@example.org");
* dc_set_config(context, "mail_pw", "***");
* dc_configure(context);
* ~~~
*
* dc_configure() returns immediately, the configuration itself may take a while
* and is done by a job in the imap-thread you've defined above.
* Once done, the #DC_EVENT_CONFIGURE_PROGRESS reports success
* to the event_handler_func() that is also defined above.
*
* The configuration result is saved in the database,
* on subsequent starts it is not needed to call dc_configure()
* (you can check this using dc_is_configured()).
*
* Now you can **send the first message:**
*
* ~~~
* // use a real testing address here
* uint32_t contact_id = dc_create_contact(context, NULL, "bob@example.org");
* uint32_t chat_id = dc_create_chat_by_contact_id(context, contact_id);
*
* dc_send_text_msg(context, chat_id, "Hi, here is my first message!");
* ~~~
*
* dc_send_text_msg() returns immediately;
* the sending itself is done by a job in the smtp-thread you've defined above.
* If you check the testing address (bob)
* and you should have received a normal email.
* Answer this email in any email program with "Got it!"
* and the imap-thread you've create above will **receive the message**.
*
* You can then **list all messages** of a chat as follow:
*
* ~~~
* dc_array_t* msglist = dc_get_chat_msgs(context, chat_id, 0, 0);
* for (int i = 0; i < dc_array_get_cnt(msglist); i++)
* {
* uint32_t msg_id = dc_array_get_id(msglist, i);
* dc_msg_t* msg = dc_get_msg(context, msg_id);
* char* text = dc_msg_get_text(msg);
*
* printf("Message %i: %s\n", i+1, text);
*
* free(text);
* dc_msg_unref(msg);
* }
* dc_array_unref(msglist);
* ~~~
*
* This will output the following two lines:
*
* ~~~
* Message 1: Hi, here is my first message!
* Message 2: Got it!
* ~~~
*
*
* ## Class reference
*
* For a class reference, see the "Classes" link atop.
*
*
* ## Further hints
*
* Here are some additional, unsorted hints that may be useful.
*
* - For `get`-functions, you have to unref the return value in some way.
*
* - Strings in function arguments or return values are usually UTF-8 encoded.
*
* - The issue-tracker for the core library is here:
* <https://github.com/deltachat/deltachat-core/issues>
*
* The following points are important mainly
* for the authors of the library itself:
*
* - For indentation, use tabs.
* Alignments that are not placed at the beginning of a line
* should be done with spaces.
*
* - For padding between functions,
* classes etc. use 2 empty lines
*
* - Source files are encoded as UTF-8 with Unix line endings
* (a simple `LF`, `0x0A` or `\n`)
*
* If you need further assistance,
* please do not hesitate to contact us
* through the channels shown at https://delta.chat/en/contribute
*
* Please keep in mind, that your derived work
* must respect the Mozilla Public License 2.0 of libdeltachat
* and the respective licenses of the libraries libdeltachat links with.
*
* See you.
*/
/* *
* @class dc_context_t
*
* An object representing a single account.
*
* Each account is linked to an IMAP/SMTP account and uses a separate
* SQLite database for offline functionality and for account-related
* settings.
*/
pub type dc_context_t = _dc_context;
/* ** library-private **********************************************************/
pub type dc_smtp_t = _dc_smtp;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_smtp {
pub etpan: *mut mailsmtp,
pub from: *mut libc::c_char,
pub esmtp: libc::c_int,
pub log_connect_errors: libc::c_int,
pub context: *mut dc_context_t,
pub error: *mut libc::c_char,
pub error_etpan: libc::c_int,
}
pub type dc_jobthread_t = _dc_jobthread;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_jobthread {
pub context: *mut dc_context_t,
pub name: *mut libc::c_char,
pub folder_config_name: *mut libc::c_char,
pub imap: *mut _dc_imap,
pub mutex: pthread_mutex_t,
pub idle_cond: pthread_cond_t,
pub idle_condflag: libc::c_int,
pub jobs_needed: libc::c_int,
pub suspended: libc::c_int,
pub using_handle: libc::c_int,
}
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_imap {
pub addr: *mut libc::c_char,
pub imap_server: *mut libc::c_char,
pub imap_port: libc::c_int,
pub imap_user: *mut libc::c_char,
pub imap_pw: *mut libc::c_char,
pub server_flags: libc::c_int,
pub connected: libc::c_int,
pub etpan: *mut mailimap,
pub idle_set_up: libc::c_int,
pub selected_folder: *mut libc::c_char,
pub selected_folder_needs_expunge: libc::c_int,
pub should_reconnect: libc::c_int,
pub can_idle: libc::c_int,
pub has_xlist: libc::c_int,
pub imap_delimiter: libc::c_char,
pub watch_folder: *mut libc::c_char,
pub watch_cond: pthread_cond_t,
pub watch_condmutex: pthread_mutex_t,
pub watch_condflag: libc::c_int,
pub fetch_type_prefetch: *mut mailimap_fetch_type,
pub fetch_type_body: *mut mailimap_fetch_type,
pub fetch_type_flags: *mut mailimap_fetch_type,
pub get_config: dc_get_config_t,
pub set_config: dc_set_config_t,
pub precheck_imf: dc_precheck_imf_t,
pub receive_imf: dc_receive_imf_t,
pub userData: *mut libc::c_void,
pub context: *mut dc_context_t,
pub log_connect_errors: libc::c_int,
pub skip_log_capabilities: libc::c_int,
}
pub type dc_receive_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: size_t,
_: *const libc::c_char,
_: uint32_t,
_: uint32_t,
) -> (),
>;
/* Purpose: Reading from IMAP servers with no dependencies to the database.
dc_context_t is only used for logging and to get information about
the online state. */
pub type dc_imap_t = _dc_imap;
pub type dc_precheck_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
_: uint32_t,
) -> libc::c_int,
>;
pub type dc_set_config_t = Option<
unsafe extern "C" fn(_: *mut dc_imap_t, _: *const libc::c_char, _: *const libc::c_char) -> (),
>;
pub type dc_get_config_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
) -> *mut libc::c_char,
>;
/* ** library-private **********************************************************/
pub type dc_sqlite3_t = _dc_sqlite3;
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_sqlite3 {
pub cobj: *mut sqlite3,
pub context: *mut dc_context_t,
}
/* yes: uppercase */
/* library private: key-history */
#[no_mangle]
pub unsafe extern "C" fn dc_add_to_keyhistory(
mut context: *mut dc_context_t,
mut rfc724_mid: *const libc::c_char,
mut sending_time: time_t,
mut addr: *const libc::c_char,
mut fingerprint: *const libc::c_char,
) {
}

866
src/dc_keyring.rs Normal file
View File

@@ -0,0 +1,866 @@
use c2rust_bitfields::BitfieldStruct;
use libc;
extern "C" {
pub type mailstream_cancel;
pub type sqlite3;
pub type sqlite3_stmt;
#[no_mangle]
fn calloc(_: libc::c_ulong, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn realloc(_: *mut libc::c_void, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn exit(_: libc::c_int) -> !;
#[no_mangle]
fn sqlite3_bind_text(
_: *mut sqlite3_stmt,
_: libc::c_int,
_: *const libc::c_char,
_: libc::c_int,
_: Option<unsafe extern "C" fn(_: *mut libc::c_void) -> ()>,
) -> libc::c_int;
#[no_mangle]
fn sqlite3_step(_: *mut sqlite3_stmt) -> libc::c_int;
#[no_mangle]
fn sqlite3_finalize(pStmt: *mut sqlite3_stmt) -> libc::c_int;
/* tools, these functions are compatible to the corresponding sqlite3_* functions */
#[no_mangle]
fn dc_sqlite3_prepare(_: *mut dc_sqlite3_t, sql: *const libc::c_char) -> *mut sqlite3_stmt;
#[no_mangle]
fn dc_key_new() -> *mut dc_key_t;
#[no_mangle]
fn dc_key_ref(_: *mut dc_key_t) -> *mut dc_key_t;
#[no_mangle]
fn dc_key_unref(_: *mut dc_key_t);
#[no_mangle]
fn dc_key_set_from_stmt(
_: *mut dc_key_t,
_: *mut sqlite3_stmt,
index: libc::c_int,
type_0: libc::c_int,
) -> libc::c_int;
}
pub type __darwin_size_t = libc::c_ulong;
pub type __darwin_ssize_t = libc::c_long;
pub type __darwin_time_t = libc::c_long;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_cond_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 40],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_mutex_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 56],
}
pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t;
pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t;
pub type size_t = __darwin_size_t;
pub type uintptr_t = libc::c_ulong;
pub type ssize_t = __darwin_ssize_t;
pub type uint8_t = libc::c_uchar;
pub type uint32_t = libc::c_uint;
pub type time_t = __darwin_time_t;
pub type pthread_cond_t = __darwin_pthread_cond_t;
pub type pthread_mutex_t = __darwin_pthread_mutex_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct carray_s {
pub array: *mut *mut libc::c_void,
pub len: libc::c_uint,
pub max: libc::c_uint,
}
pub type carray = carray_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream {
pub buffer_max_size: size_t,
pub write_buffer: *mut libc::c_char,
pub write_buffer_len: size_t,
pub read_buffer: *mut libc::c_char,
pub read_buffer_len: size_t,
pub low: *mut mailstream_low,
pub idle: *mut mailstream_cancel,
pub idling: libc::c_int,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
pub type mailstream = _mailstream;
pub type mailstream_low = _mailstream_low;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream_low {
pub data: *mut libc::c_void,
pub driver: *mut mailstream_low_driver,
pub privacy: libc::c_int,
pub identifier: *mut libc::c_char,
pub timeout: libc::c_ulong,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream_low,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailstream_low_driver {
pub mailstream_read: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *mut libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_write: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *const libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_close: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_get_fd: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_free: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_cancel: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_get_cancel:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut mailstream_cancel>,
pub mailstream_get_certificate_chain:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut carray>,
pub mailstream_setup_idle: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_unsetup_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_interrupt_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
}
pub type progress_function = unsafe extern "C" fn(_: size_t, _: size_t) -> ();
pub type mailprogress_function =
unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _MMAPString {
pub str_0: *mut libc::c_char,
pub len: size_t,
pub allocated_len: size_t,
pub fd: libc::c_int,
pub mmapped_size: size_t,
}
pub type MMAPString = _MMAPString;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clistcell_s {
pub data: *mut libc::c_void,
pub previous: *mut clistcell_s,
pub next: *mut clistcell_s,
}
pub type clistcell = clistcell_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clist_s {
pub first: *mut clistcell,
pub last: *mut clistcell,
pub count: libc::c_int,
}
pub type clist = clist_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailsmtp {
pub stream: *mut mailstream,
pub progr_rate: size_t,
pub progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub response: *mut libc::c_char,
pub line_buffer: *mut MMAPString,
pub response_buffer: *mut MMAPString,
pub esmtp: libc::c_int,
pub auth: libc::c_int,
pub smtp_sasl: unnamed,
pub smtp_max_msg_size: size_t,
pub smtp_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub smtp_progress_context: *mut libc::c_void,
pub response_code: libc::c_int,
pub smtp_timeout: time_t,
pub smtp_logger: Option<
unsafe extern "C" fn(
_: *mut mailsmtp,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub smtp_logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_capability_data {
pub cap_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att_body_section {
pub sec_section: *mut mailimap_section,
pub sec_origin_octet: uint32_t,
pub sec_body_part: *mut libc::c_char,
pub sec_length: size_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section {
pub sec_spec: *mut mailimap_section_spec,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_spec {
pub sec_type: libc::c_int,
pub sec_data: unnamed_0,
pub sec_text: *mut mailimap_section_text,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_text {
pub sec_type: libc::c_int,
pub sec_msgtext: *mut mailimap_section_msgtext,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_msgtext {
pub sec_type: libc::c_int,
pub sec_header_list: *mut mailimap_header_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_header_list {
pub hdr_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_0 {
pub sec_msgtext: *mut mailimap_section_msgtext,
pub sec_part: *mut mailimap_section_part,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_part {
pub sec_id: *mut clist,
}
pub type mailimap_msg_body_handler = unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_flag_list {
pub fl_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_mailbox_data_status {
pub st_mailbox: *mut libc::c_char,
pub st_info_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att {
pub att_list: *mut clist,
pub att_number: uint32_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_att {
pub att_type: libc::c_int,
pub att_section: *mut mailimap_section,
pub att_offset: uint32_t,
pub att_size: uint32_t,
pub att_extension: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_type {
pub ft_type: libc::c_int,
pub ft_data: unnamed_1,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_1 {
pub ft_fetch_att: *mut mailimap_fetch_att,
pub ft_fetch_att_list: *mut clist,
}
pub type mailimap_msg_att_handler =
unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap {
pub imap_response: *mut libc::c_char,
pub imap_stream: *mut mailstream,
pub imap_progr_rate: size_t,
pub imap_progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub imap_stream_buffer: *mut MMAPString,
pub imap_response_buffer: *mut MMAPString,
pub imap_state: libc::c_int,
pub imap_tag: libc::c_int,
pub imap_connection_info: *mut mailimap_connection_info,
pub imap_selection_info: *mut mailimap_selection_info,
pub imap_response_info: *mut mailimap_response_info,
pub imap_sasl: unnamed_2,
pub imap_idle_timestamp: time_t,
pub imap_idle_maxdelay: time_t,
pub imap_body_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_items_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_progress_context: *mut libc::c_void,
pub imap_msg_att_handler:
Option<unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ()>,
pub imap_msg_att_handler_context: *mut libc::c_void,
pub imap_msg_body_handler: Option<
unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool,
>,
pub imap_msg_body_handler_context: *mut libc::c_void,
pub imap_timeout: time_t,
pub imap_logger: Option<
unsafe extern "C" fn(
_: *mut mailimap,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub imap_logger_context: *mut libc::c_void,
pub is_163_workaround_enabled: libc::c_int,
pub is_rambler_workaround_enabled: libc::c_int,
pub is_qip_workaround_enabled: libc::c_int,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed_2 {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_response_info {
pub rsp_alert: *mut libc::c_char,
pub rsp_parse: *mut libc::c_char,
pub rsp_badcharset: *mut clist,
pub rsp_trycreate: libc::c_int,
pub rsp_mailbox_list: *mut clist,
pub rsp_mailbox_lsub: *mut clist,
pub rsp_search_result: *mut clist,
pub rsp_status: *mut mailimap_mailbox_data_status,
pub rsp_expunged: *mut clist,
pub rsp_fetch_list: *mut clist,
pub rsp_extension_list: *mut clist,
pub rsp_atom: *mut libc::c_char,
pub rsp_value: *mut libc::c_char,
}
#[derive(BitfieldStruct, Clone, Copy)]
#[repr(C)]
pub struct mailimap_selection_info {
pub sel_perm_flags: *mut clist,
pub sel_perm: libc::c_int,
pub sel_uidnext: uint32_t,
pub sel_uidvalidity: uint32_t,
pub sel_first_unseen: uint32_t,
pub sel_flags: *mut mailimap_flag_list,
pub sel_exists: uint32_t,
pub sel_recent: uint32_t,
pub sel_unseen: uint32_t,
#[bitfield(name = "sel_has_exists", ty = "uint8_t", bits = "0..=0")]
#[bitfield(name = "sel_has_recent", ty = "uint8_t", bits = "1..=1")]
pub sel_has_exists_sel_has_recent: [u8; 1],
pub _pad: [u8; 3],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_connection_info {
pub imap_capability: *mut mailimap_capability_data,
}
/* define DC_USE_RPGP to enable use of rPGP instead of netpgp where available;
preferrably, this should be done in the project configuration currently */
//#define DC_USE_RPGP 1
/* Includes that are used frequently. This file may also be used to create predefined headers. */
/* * Structure behind dc_context_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_context {
pub magic: uint32_t,
pub userdata: *mut libc::c_void,
pub dbfile: *mut libc::c_char,
pub blobdir: *mut libc::c_char,
pub sql: *mut dc_sqlite3_t,
pub inbox: *mut dc_imap_t,
pub inboxidle_condmutex: pthread_mutex_t,
pub perform_inbox_jobs_needed: libc::c_int,
pub probe_imap_network: libc::c_int,
pub sentbox_thread: dc_jobthread_t,
pub mvbox_thread: dc_jobthread_t,
pub smtp: *mut dc_smtp_t,
pub smtpidle_cond: pthread_cond_t,
pub smtpidle_condmutex: pthread_mutex_t,
pub smtpidle_condflag: libc::c_int,
pub smtp_suspended: libc::c_int,
pub smtp_doing_jobs: libc::c_int,
pub perform_smtp_jobs_needed: libc::c_int,
pub probe_smtp_network: libc::c_int,
pub oauth2_critical: pthread_mutex_t,
pub cb: dc_callback_t,
pub os_name: *mut libc::c_char,
pub cmdline_sel_chat_id: uint32_t,
pub bob_expects: libc::c_int,
pub bobs_status: libc::c_int,
pub bobs_qr_scan: *mut dc_lot_t,
pub bobs_qr_critical: pthread_mutex_t,
pub last_smeared_timestamp: time_t,
pub smear_critical: pthread_mutex_t,
pub ongoing_running: libc::c_int,
pub shall_stop_ongoing: libc::c_int,
}
pub type dc_lot_t = _dc_lot;
/* * Structure behind dc_lot_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_lot {
pub magic: uint32_t,
pub text1_meaning: libc::c_int,
pub text1: *mut libc::c_char,
pub text2: *mut libc::c_char,
pub timestamp: time_t,
pub state: libc::c_int,
pub id: uint32_t,
pub fingerprint: *mut libc::c_char,
pub invitenumber: *mut libc::c_char,
pub auth: *mut libc::c_char,
}
/* *
* Callback function that should be given to dc_context_new().
*
* @memberof dc_context_t
* @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 = Option<
unsafe extern "C" fn(
_: *mut dc_context_t,
_: libc::c_int,
_: uintptr_t,
_: uintptr_t,
) -> uintptr_t,
>;
/* *
* @mainpage Getting started
*
* This document describes how to handle the Delta Chat core library.
* For general information about Delta Chat itself,
* see <https://delta.chat> and <https://github.com/deltachat>.
*
* Let's start.
*
* First of all, you have to **define an event-handler-function**
* that is called by the library on specific events
* (eg. when the configuration is done or when fresh messages arrive).
* With this function you can create a Delta Chat context then:
*
* ~~~
* #include <deltachat.h>
*
* uintptr_t event_handler_func(dc_context_t* context, int event,
* uintptr_t data1, uintptr_t data2)
* {
* return 0; // for unhandled events, it is always safe to return 0
* }
*
* dc_context_t* context = dc_context_new(event_handler_func, NULL, NULL);
* ~~~
*
* After that, you should make sure,
* sending and receiving jobs are processed as needed.
* For this purpose, you have to **create two threads:**
*
* ~~~
* #include <pthread.h>
*
* void* imap_thread_func(void* context)
* {
* while (true) {
* dc_perform_imap_jobs(context);
* dc_perform_imap_fetch(context);
* dc_perform_imap_idle(context);
* }
* }
*
* void* smtp_thread_func(void* context)
* {
* while (true) {
* dc_perform_smtp_jobs(context);
* dc_perform_smtp_idle(context);
* }
* }
*
* static pthread_t imap_thread, smtp_thread;
* pthread_create(&imap_thread, NULL, imap_thread_func, context);
* pthread_create(&smtp_thread, NULL, smtp_thread_func, context);
* ~~~
*
* The example above uses "pthreads",
* however, you can also use anything else for thread handling.
* NB: The deltachat-core library itself does not create any threads on its own,
* however, functions, unless stated otherwise, are thread-safe.
*
* After that you can **define and open a database.**
* The database is a normal sqlite-file and is created as needed:
*
* ~~~
* dc_open(context, "example.db", NULL);
* ~~~
*
* Now you can **configure the context:**
*
* ~~~
* // use some real test credentials here
* dc_set_config(context, "addr", "alice@example.org");
* dc_set_config(context, "mail_pw", "***");
* dc_configure(context);
* ~~~
*
* dc_configure() returns immediately, the configuration itself may take a while
* and is done by a job in the imap-thread you've defined above.
* Once done, the #DC_EVENT_CONFIGURE_PROGRESS reports success
* to the event_handler_func() that is also defined above.
*
* The configuration result is saved in the database,
* on subsequent starts it is not needed to call dc_configure()
* (you can check this using dc_is_configured()).
*
* Now you can **send the first message:**
*
* ~~~
* // use a real testing address here
* uint32_t contact_id = dc_create_contact(context, NULL, "bob@example.org");
* uint32_t chat_id = dc_create_chat_by_contact_id(context, contact_id);
*
* dc_send_text_msg(context, chat_id, "Hi, here is my first message!");
* ~~~
*
* dc_send_text_msg() returns immediately;
* the sending itself is done by a job in the smtp-thread you've defined above.
* If you check the testing address (bob)
* and you should have received a normal email.
* Answer this email in any email program with "Got it!"
* and the imap-thread you've create above will **receive the message**.
*
* You can then **list all messages** of a chat as follow:
*
* ~~~
* dc_array_t* msglist = dc_get_chat_msgs(context, chat_id, 0, 0);
* for (int i = 0; i < dc_array_get_cnt(msglist); i++)
* {
* uint32_t msg_id = dc_array_get_id(msglist, i);
* dc_msg_t* msg = dc_get_msg(context, msg_id);
* char* text = dc_msg_get_text(msg);
*
* printf("Message %i: %s\n", i+1, text);
*
* free(text);
* dc_msg_unref(msg);
* }
* dc_array_unref(msglist);
* ~~~
*
* This will output the following two lines:
*
* ~~~
* Message 1: Hi, here is my first message!
* Message 2: Got it!
* ~~~
*
*
* ## Class reference
*
* For a class reference, see the "Classes" link atop.
*
*
* ## Further hints
*
* Here are some additional, unsorted hints that may be useful.
*
* - For `get`-functions, you have to unref the return value in some way.
*
* - Strings in function arguments or return values are usually UTF-8 encoded.
*
* - The issue-tracker for the core library is here:
* <https://github.com/deltachat/deltachat-core/issues>
*
* The following points are important mainly
* for the authors of the library itself:
*
* - For indentation, use tabs.
* Alignments that are not placed at the beginning of a line
* should be done with spaces.
*
* - For padding between functions,
* classes etc. use 2 empty lines
*
* - Source files are encoded as UTF-8 with Unix line endings
* (a simple `LF`, `0x0A` or `\n`)
*
* If you need further assistance,
* please do not hesitate to contact us
* through the channels shown at https://delta.chat/en/contribute
*
* Please keep in mind, that your derived work
* must respect the Mozilla Public License 2.0 of libdeltachat
* and the respective licenses of the libraries libdeltachat links with.
*
* See you.
*/
/* *
* @class dc_context_t
*
* An object representing a single account.
*
* Each account is linked to an IMAP/SMTP account and uses a separate
* SQLite database for offline functionality and for account-related
* settings.
*/
pub type dc_context_t = _dc_context;
/* ** library-private **********************************************************/
pub type dc_smtp_t = _dc_smtp;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_smtp {
pub etpan: *mut mailsmtp,
pub from: *mut libc::c_char,
pub esmtp: libc::c_int,
pub log_connect_errors: libc::c_int,
pub context: *mut dc_context_t,
pub error: *mut libc::c_char,
pub error_etpan: libc::c_int,
}
pub type dc_jobthread_t = _dc_jobthread;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_jobthread {
pub context: *mut dc_context_t,
pub name: *mut libc::c_char,
pub folder_config_name: *mut libc::c_char,
pub imap: *mut _dc_imap,
pub mutex: pthread_mutex_t,
pub idle_cond: pthread_cond_t,
pub idle_condflag: libc::c_int,
pub jobs_needed: libc::c_int,
pub suspended: libc::c_int,
pub using_handle: libc::c_int,
}
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_imap {
pub addr: *mut libc::c_char,
pub imap_server: *mut libc::c_char,
pub imap_port: libc::c_int,
pub imap_user: *mut libc::c_char,
pub imap_pw: *mut libc::c_char,
pub server_flags: libc::c_int,
pub connected: libc::c_int,
pub etpan: *mut mailimap,
pub idle_set_up: libc::c_int,
pub selected_folder: *mut libc::c_char,
pub selected_folder_needs_expunge: libc::c_int,
pub should_reconnect: libc::c_int,
pub can_idle: libc::c_int,
pub has_xlist: libc::c_int,
pub imap_delimiter: libc::c_char,
pub watch_folder: *mut libc::c_char,
pub watch_cond: pthread_cond_t,
pub watch_condmutex: pthread_mutex_t,
pub watch_condflag: libc::c_int,
pub fetch_type_prefetch: *mut mailimap_fetch_type,
pub fetch_type_body: *mut mailimap_fetch_type,
pub fetch_type_flags: *mut mailimap_fetch_type,
pub get_config: dc_get_config_t,
pub set_config: dc_set_config_t,
pub precheck_imf: dc_precheck_imf_t,
pub receive_imf: dc_receive_imf_t,
pub userData: *mut libc::c_void,
pub context: *mut dc_context_t,
pub log_connect_errors: libc::c_int,
pub skip_log_capabilities: libc::c_int,
}
pub type dc_receive_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: size_t,
_: *const libc::c_char,
_: uint32_t,
_: uint32_t,
) -> (),
>;
/* Purpose: Reading from IMAP servers with no dependencies to the database.
dc_context_t is only used for logging and to get information about
the online state. */
pub type dc_imap_t = _dc_imap;
pub type dc_precheck_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
_: uint32_t,
) -> libc::c_int,
>;
pub type dc_set_config_t = Option<
unsafe extern "C" fn(_: *mut dc_imap_t, _: *const libc::c_char, _: *const libc::c_char) -> (),
>;
pub type dc_get_config_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
) -> *mut libc::c_char,
>;
/* ** library-private **********************************************************/
pub type dc_sqlite3_t = _dc_sqlite3;
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_sqlite3 {
pub cobj: *mut sqlite3,
pub context: *mut dc_context_t,
}
pub type sqlite3_destructor_type = Option<unsafe extern "C" fn(_: *mut libc::c_void) -> ()>;
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_key {
pub binary: *mut libc::c_void,
pub bytes: libc::c_int,
pub type_0: libc::c_int,
pub _m_heap_refcnt: libc::c_int,
}
pub type dc_key_t = _dc_key;
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_keyring {
pub keys: *mut *mut dc_key_t,
pub count: libc::c_int,
pub allocated: libc::c_int,
}
pub type dc_keyring_t = _dc_keyring;
#[no_mangle]
pub unsafe extern "C" fn dc_keyring_new() -> *mut dc_keyring_t {
let mut keyring: *mut dc_keyring_t = 0 as *mut dc_keyring_t;
keyring = calloc(
1i32 as libc::c_ulong,
::std::mem::size_of::<dc_keyring_t>() as libc::c_ulong,
) as *mut dc_keyring_t;
if keyring.is_null() {
exit(42i32);
}
return keyring;
}
#[no_mangle]
pub unsafe extern "C" fn dc_keyring_unref(mut keyring: *mut dc_keyring_t) {
if keyring.is_null() {
return;
}
let mut i: libc::c_int = 0i32;
while i < (*keyring).count {
dc_key_unref(*(*keyring).keys.offset(i as isize));
i += 1
}
free((*keyring).keys as *mut libc::c_void);
free(keyring as *mut libc::c_void);
}
/* the reference counter of the key is increased by one */
#[no_mangle]
pub unsafe extern "C" fn dc_keyring_add(mut keyring: *mut dc_keyring_t, mut to_add: *mut dc_key_t) {
if keyring.is_null() || to_add.is_null() {
return;
}
if (*keyring).count == (*keyring).allocated {
let mut newsize: libc::c_int = (*keyring).allocated * 2i32 + 10i32;
(*keyring).keys = realloc(
(*keyring).keys as *mut libc::c_void,
(newsize as libc::c_ulong)
.wrapping_mul(::std::mem::size_of::<*mut dc_key_t>() as libc::c_ulong),
) as *mut *mut dc_key_t;
if (*keyring).keys.is_null() {
exit(41i32);
}
(*keyring).allocated = newsize
}
let ref mut fresh0 = *(*keyring).keys.offset((*keyring).count as isize);
*fresh0 = dc_key_ref(to_add);
(*keyring).count += 1;
}
#[no_mangle]
pub unsafe extern "C" fn dc_keyring_load_self_private_for_decrypting(
mut keyring: *mut dc_keyring_t,
mut self_addr: *const libc::c_char,
mut sql: *mut dc_sqlite3_t,
) -> libc::c_int {
if keyring.is_null() || self_addr.is_null() || sql.is_null() {
return 0i32;
}
let mut stmt: *mut sqlite3_stmt = dc_sqlite3_prepare(
sql,
b"SELECT private_key FROM keypairs ORDER BY addr=? DESC, is_default DESC;\x00" as *const u8
as *const libc::c_char,
);
sqlite3_bind_text(stmt, 1i32, self_addr, -1i32, None);
while sqlite3_step(stmt) == 100i32 {
let mut key: *mut dc_key_t = dc_key_new();
if 0 != dc_key_set_from_stmt(key, stmt, 0i32, 1i32) {
dc_keyring_add(keyring, key);
}
dc_key_unref(key);
}
sqlite3_finalize(stmt);
return 1i32;
}

1884
src/dc_location.rs Normal file

File diff suppressed because it is too large Load Diff

852
src/dc_log.rs Normal file
View File

@@ -0,0 +1,852 @@
use c2rust_bitfields::BitfieldStruct;
use libc;
extern "C" {
pub type mailstream_cancel;
pub type sqlite3;
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn vsnprintf(
_: *mut libc::c_char,
_: libc::c_ulong,
_: *const libc::c_char,
_: ::std::ffi::VaList,
) -> libc::c_int;
/* string tools */
#[no_mangle]
fn dc_strdup(_: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn dc_mprintf(format: *const libc::c_char, _: ...) -> *mut libc::c_char;
}
pub type __builtin_va_list = [__va_list_tag; 1];
#[derive(Copy, Clone)]
#[repr(C)]
pub struct __va_list_tag {
pub gp_offset: libc::c_uint,
pub fp_offset: libc::c_uint,
pub overflow_arg_area: *mut libc::c_void,
pub reg_save_area: *mut libc::c_void,
}
pub type va_list = __builtin_va_list;
pub type __darwin_size_t = libc::c_ulong;
pub type __darwin_ssize_t = libc::c_long;
pub type __darwin_time_t = libc::c_long;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_cond_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 40],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_mutex_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 56],
}
pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t;
pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t;
pub type size_t = __darwin_size_t;
pub type uintptr_t = libc::c_ulong;
pub type ssize_t = __darwin_ssize_t;
pub type uint8_t = libc::c_uchar;
pub type uint32_t = libc::c_uint;
pub type time_t = __darwin_time_t;
pub type pthread_cond_t = __darwin_pthread_cond_t;
pub type pthread_mutex_t = __darwin_pthread_mutex_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct carray_s {
pub array: *mut *mut libc::c_void,
pub len: libc::c_uint,
pub max: libc::c_uint,
}
pub type carray = carray_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream {
pub buffer_max_size: size_t,
pub write_buffer: *mut libc::c_char,
pub write_buffer_len: size_t,
pub read_buffer: *mut libc::c_char,
pub read_buffer_len: size_t,
pub low: *mut mailstream_low,
pub idle: *mut mailstream_cancel,
pub idling: libc::c_int,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
pub type mailstream = _mailstream;
pub type mailstream_low = _mailstream_low;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream_low {
pub data: *mut libc::c_void,
pub driver: *mut mailstream_low_driver,
pub privacy: libc::c_int,
pub identifier: *mut libc::c_char,
pub timeout: libc::c_ulong,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream_low,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailstream_low_driver {
pub mailstream_read: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *mut libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_write: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *const libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_close: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_get_fd: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_free: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_cancel: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_get_cancel:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut mailstream_cancel>,
pub mailstream_get_certificate_chain:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut carray>,
pub mailstream_setup_idle: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_unsetup_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_interrupt_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
}
pub type progress_function = unsafe extern "C" fn(_: size_t, _: size_t) -> ();
pub type mailprogress_function =
unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _MMAPString {
pub str_0: *mut libc::c_char,
pub len: size_t,
pub allocated_len: size_t,
pub fd: libc::c_int,
pub mmapped_size: size_t,
}
pub type MMAPString = _MMAPString;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clistcell_s {
pub data: *mut libc::c_void,
pub previous: *mut clistcell_s,
pub next: *mut clistcell_s,
}
pub type clistcell = clistcell_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clist_s {
pub first: *mut clistcell,
pub last: *mut clistcell,
pub count: libc::c_int,
}
pub type clist = clist_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailsmtp {
pub stream: *mut mailstream,
pub progr_rate: size_t,
pub progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub response: *mut libc::c_char,
pub line_buffer: *mut MMAPString,
pub response_buffer: *mut MMAPString,
pub esmtp: libc::c_int,
pub auth: libc::c_int,
pub smtp_sasl: unnamed,
pub smtp_max_msg_size: size_t,
pub smtp_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub smtp_progress_context: *mut libc::c_void,
pub response_code: libc::c_int,
pub smtp_timeout: time_t,
pub smtp_logger: Option<
unsafe extern "C" fn(
_: *mut mailsmtp,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub smtp_logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_capability_data {
pub cap_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att_body_section {
pub sec_section: *mut mailimap_section,
pub sec_origin_octet: uint32_t,
pub sec_body_part: *mut libc::c_char,
pub sec_length: size_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section {
pub sec_spec: *mut mailimap_section_spec,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_spec {
pub sec_type: libc::c_int,
pub sec_data: unnamed_0,
pub sec_text: *mut mailimap_section_text,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_text {
pub sec_type: libc::c_int,
pub sec_msgtext: *mut mailimap_section_msgtext,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_msgtext {
pub sec_type: libc::c_int,
pub sec_header_list: *mut mailimap_header_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_header_list {
pub hdr_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_0 {
pub sec_msgtext: *mut mailimap_section_msgtext,
pub sec_part: *mut mailimap_section_part,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_part {
pub sec_id: *mut clist,
}
pub type mailimap_msg_body_handler = unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_flag_list {
pub fl_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_mailbox_data_status {
pub st_mailbox: *mut libc::c_char,
pub st_info_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att {
pub att_list: *mut clist,
pub att_number: uint32_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_att {
pub att_type: libc::c_int,
pub att_section: *mut mailimap_section,
pub att_offset: uint32_t,
pub att_size: uint32_t,
pub att_extension: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_type {
pub ft_type: libc::c_int,
pub ft_data: unnamed_1,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_1 {
pub ft_fetch_att: *mut mailimap_fetch_att,
pub ft_fetch_att_list: *mut clist,
}
pub type mailimap_msg_att_handler =
unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap {
pub imap_response: *mut libc::c_char,
pub imap_stream: *mut mailstream,
pub imap_progr_rate: size_t,
pub imap_progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub imap_stream_buffer: *mut MMAPString,
pub imap_response_buffer: *mut MMAPString,
pub imap_state: libc::c_int,
pub imap_tag: libc::c_int,
pub imap_connection_info: *mut mailimap_connection_info,
pub imap_selection_info: *mut mailimap_selection_info,
pub imap_response_info: *mut mailimap_response_info,
pub imap_sasl: unnamed_2,
pub imap_idle_timestamp: time_t,
pub imap_idle_maxdelay: time_t,
pub imap_body_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_items_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_progress_context: *mut libc::c_void,
pub imap_msg_att_handler:
Option<unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ()>,
pub imap_msg_att_handler_context: *mut libc::c_void,
pub imap_msg_body_handler: Option<
unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool,
>,
pub imap_msg_body_handler_context: *mut libc::c_void,
pub imap_timeout: time_t,
pub imap_logger: Option<
unsafe extern "C" fn(
_: *mut mailimap,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub imap_logger_context: *mut libc::c_void,
pub is_163_workaround_enabled: libc::c_int,
pub is_rambler_workaround_enabled: libc::c_int,
pub is_qip_workaround_enabled: libc::c_int,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed_2 {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_response_info {
pub rsp_alert: *mut libc::c_char,
pub rsp_parse: *mut libc::c_char,
pub rsp_badcharset: *mut clist,
pub rsp_trycreate: libc::c_int,
pub rsp_mailbox_list: *mut clist,
pub rsp_mailbox_lsub: *mut clist,
pub rsp_search_result: *mut clist,
pub rsp_status: *mut mailimap_mailbox_data_status,
pub rsp_expunged: *mut clist,
pub rsp_fetch_list: *mut clist,
pub rsp_extension_list: *mut clist,
pub rsp_atom: *mut libc::c_char,
pub rsp_value: *mut libc::c_char,
}
#[derive(BitfieldStruct, Clone, Copy)]
#[repr(C)]
pub struct mailimap_selection_info {
pub sel_perm_flags: *mut clist,
pub sel_perm: libc::c_int,
pub sel_uidnext: uint32_t,
pub sel_uidvalidity: uint32_t,
pub sel_first_unseen: uint32_t,
pub sel_flags: *mut mailimap_flag_list,
pub sel_exists: uint32_t,
pub sel_recent: uint32_t,
pub sel_unseen: uint32_t,
#[bitfield(name = "sel_has_exists", ty = "uint8_t", bits = "0..=0")]
#[bitfield(name = "sel_has_recent", ty = "uint8_t", bits = "1..=1")]
pub sel_has_exists_sel_has_recent: [u8; 1],
pub _pad: [u8; 3],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_connection_info {
pub imap_capability: *mut mailimap_capability_data,
}
/* define DC_USE_RPGP to enable use of rPGP instead of netpgp where available;
preferrably, this should be done in the project configuration currently */
//#define DC_USE_RPGP 1
/* Includes that are used frequently. This file may also be used to create predefined headers. */
/* * Structure behind dc_context_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_context {
pub magic: uint32_t,
pub userdata: *mut libc::c_void,
pub dbfile: *mut libc::c_char,
pub blobdir: *mut libc::c_char,
pub sql: *mut dc_sqlite3_t,
pub inbox: *mut dc_imap_t,
pub inboxidle_condmutex: pthread_mutex_t,
pub perform_inbox_jobs_needed: libc::c_int,
pub probe_imap_network: libc::c_int,
pub sentbox_thread: dc_jobthread_t,
pub mvbox_thread: dc_jobthread_t,
pub smtp: *mut dc_smtp_t,
pub smtpidle_cond: pthread_cond_t,
pub smtpidle_condmutex: pthread_mutex_t,
pub smtpidle_condflag: libc::c_int,
pub smtp_suspended: libc::c_int,
pub smtp_doing_jobs: libc::c_int,
pub perform_smtp_jobs_needed: libc::c_int,
pub probe_smtp_network: libc::c_int,
pub oauth2_critical: pthread_mutex_t,
pub cb: dc_callback_t,
pub os_name: *mut libc::c_char,
pub cmdline_sel_chat_id: uint32_t,
pub bob_expects: libc::c_int,
pub bobs_status: libc::c_int,
pub bobs_qr_scan: *mut dc_lot_t,
pub bobs_qr_critical: pthread_mutex_t,
pub last_smeared_timestamp: time_t,
pub smear_critical: pthread_mutex_t,
pub ongoing_running: libc::c_int,
pub shall_stop_ongoing: libc::c_int,
}
pub type dc_lot_t = _dc_lot;
/* * Structure behind dc_lot_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_lot {
pub magic: uint32_t,
pub text1_meaning: libc::c_int,
pub text1: *mut libc::c_char,
pub text2: *mut libc::c_char,
pub timestamp: time_t,
pub state: libc::c_int,
pub id: uint32_t,
pub fingerprint: *mut libc::c_char,
pub invitenumber: *mut libc::c_char,
pub auth: *mut libc::c_char,
}
/* *
* Callback function that should be given to dc_context_new().
*
* @memberof dc_context_t
* @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 = Option<
unsafe extern "C" fn(
_: *mut dc_context_t,
_: libc::c_int,
_: uintptr_t,
_: uintptr_t,
) -> uintptr_t,
>;
/* *
* @mainpage Getting started
*
* This document describes how to handle the Delta Chat core library.
* For general information about Delta Chat itself,
* see <https://delta.chat> and <https://github.com/deltachat>.
*
* Let's start.
*
* First of all, you have to **define an event-handler-function**
* that is called by the library on specific events
* (eg. when the configuration is done or when fresh messages arrive).
* With this function you can create a Delta Chat context then:
*
* ~~~
* #include <deltachat.h>
*
* uintptr_t event_handler_func(dc_context_t* context, int event,
* uintptr_t data1, uintptr_t data2)
* {
* return 0; // for unhandled events, it is always safe to return 0
* }
*
* dc_context_t* context = dc_context_new(event_handler_func, NULL, NULL);
* ~~~
*
* After that, you should make sure,
* sending and receiving jobs are processed as needed.
* For this purpose, you have to **create two threads:**
*
* ~~~
* #include <pthread.h>
*
* void* imap_thread_func(void* context)
* {
* while (true) {
* dc_perform_imap_jobs(context);
* dc_perform_imap_fetch(context);
* dc_perform_imap_idle(context);
* }
* }
*
* void* smtp_thread_func(void* context)
* {
* while (true) {
* dc_perform_smtp_jobs(context);
* dc_perform_smtp_idle(context);
* }
* }
*
* static pthread_t imap_thread, smtp_thread;
* pthread_create(&imap_thread, NULL, imap_thread_func, context);
* pthread_create(&smtp_thread, NULL, smtp_thread_func, context);
* ~~~
*
* The example above uses "pthreads",
* however, you can also use anything else for thread handling.
* NB: The deltachat-core library itself does not create any threads on its own,
* however, functions, unless stated otherwise, are thread-safe.
*
* After that you can **define and open a database.**
* The database is a normal sqlite-file and is created as needed:
*
* ~~~
* dc_open(context, "example.db", NULL);
* ~~~
*
* Now you can **configure the context:**
*
* ~~~
* // use some real test credentials here
* dc_set_config(context, "addr", "alice@example.org");
* dc_set_config(context, "mail_pw", "***");
* dc_configure(context);
* ~~~
*
* dc_configure() returns immediately, the configuration itself may take a while
* and is done by a job in the imap-thread you've defined above.
* Once done, the #DC_EVENT_CONFIGURE_PROGRESS reports success
* to the event_handler_func() that is also defined above.
*
* The configuration result is saved in the database,
* on subsequent starts it is not needed to call dc_configure()
* (you can check this using dc_is_configured()).
*
* Now you can **send the first message:**
*
* ~~~
* // use a real testing address here
* uint32_t contact_id = dc_create_contact(context, NULL, "bob@example.org");
* uint32_t chat_id = dc_create_chat_by_contact_id(context, contact_id);
*
* dc_send_text_msg(context, chat_id, "Hi, here is my first message!");
* ~~~
*
* dc_send_text_msg() returns immediately;
* the sending itself is done by a job in the smtp-thread you've defined above.
* If you check the testing address (bob)
* and you should have received a normal email.
* Answer this email in any email program with "Got it!"
* and the imap-thread you've create above will **receive the message**.
*
* You can then **list all messages** of a chat as follow:
*
* ~~~
* dc_array_t* msglist = dc_get_chat_msgs(context, chat_id, 0, 0);
* for (int i = 0; i < dc_array_get_cnt(msglist); i++)
* {
* uint32_t msg_id = dc_array_get_id(msglist, i);
* dc_msg_t* msg = dc_get_msg(context, msg_id);
* char* text = dc_msg_get_text(msg);
*
* printf("Message %i: %s\n", i+1, text);
*
* free(text);
* dc_msg_unref(msg);
* }
* dc_array_unref(msglist);
* ~~~
*
* This will output the following two lines:
*
* ~~~
* Message 1: Hi, here is my first message!
* Message 2: Got it!
* ~~~
*
*
* ## Class reference
*
* For a class reference, see the "Classes" link atop.
*
*
* ## Further hints
*
* Here are some additional, unsorted hints that may be useful.
*
* - For `get`-functions, you have to unref the return value in some way.
*
* - Strings in function arguments or return values are usually UTF-8 encoded.
*
* - The issue-tracker for the core library is here:
* <https://github.com/deltachat/deltachat-core/issues>
*
* The following points are important mainly
* for the authors of the library itself:
*
* - For indentation, use tabs.
* Alignments that are not placed at the beginning of a line
* should be done with spaces.
*
* - For padding between functions,
* classes etc. use 2 empty lines
*
* - Source files are encoded as UTF-8 with Unix line endings
* (a simple `LF`, `0x0A` or `\n`)
*
* If you need further assistance,
* please do not hesitate to contact us
* through the channels shown at https://delta.chat/en/contribute
*
* Please keep in mind, that your derived work
* must respect the Mozilla Public License 2.0 of libdeltachat
* and the respective licenses of the libraries libdeltachat links with.
*
* See you.
*/
/* *
* @class dc_context_t
*
* An object representing a single account.
*
* Each account is linked to an IMAP/SMTP account and uses a separate
* SQLite database for offline functionality and for account-related
* settings.
*/
pub type dc_context_t = _dc_context;
/* ** library-private **********************************************************/
pub type dc_smtp_t = _dc_smtp;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_smtp {
pub etpan: *mut mailsmtp,
pub from: *mut libc::c_char,
pub esmtp: libc::c_int,
pub log_connect_errors: libc::c_int,
pub context: *mut dc_context_t,
pub error: *mut libc::c_char,
pub error_etpan: libc::c_int,
}
pub type dc_jobthread_t = _dc_jobthread;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_jobthread {
pub context: *mut dc_context_t,
pub name: *mut libc::c_char,
pub folder_config_name: *mut libc::c_char,
pub imap: *mut _dc_imap,
pub mutex: pthread_mutex_t,
pub idle_cond: pthread_cond_t,
pub idle_condflag: libc::c_int,
pub jobs_needed: libc::c_int,
pub suspended: libc::c_int,
pub using_handle: libc::c_int,
}
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_imap {
pub addr: *mut libc::c_char,
pub imap_server: *mut libc::c_char,
pub imap_port: libc::c_int,
pub imap_user: *mut libc::c_char,
pub imap_pw: *mut libc::c_char,
pub server_flags: libc::c_int,
pub connected: libc::c_int,
pub etpan: *mut mailimap,
pub idle_set_up: libc::c_int,
pub selected_folder: *mut libc::c_char,
pub selected_folder_needs_expunge: libc::c_int,
pub should_reconnect: libc::c_int,
pub can_idle: libc::c_int,
pub has_xlist: libc::c_int,
pub imap_delimiter: libc::c_char,
pub watch_folder: *mut libc::c_char,
pub watch_cond: pthread_cond_t,
pub watch_condmutex: pthread_mutex_t,
pub watch_condflag: libc::c_int,
pub fetch_type_prefetch: *mut mailimap_fetch_type,
pub fetch_type_body: *mut mailimap_fetch_type,
pub fetch_type_flags: *mut mailimap_fetch_type,
pub get_config: dc_get_config_t,
pub set_config: dc_set_config_t,
pub precheck_imf: dc_precheck_imf_t,
pub receive_imf: dc_receive_imf_t,
pub userData: *mut libc::c_void,
pub context: *mut dc_context_t,
pub log_connect_errors: libc::c_int,
pub skip_log_capabilities: libc::c_int,
}
pub type dc_receive_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: size_t,
_: *const libc::c_char,
_: uint32_t,
_: uint32_t,
) -> (),
>;
/* Purpose: Reading from IMAP servers with no dependencies to the database.
dc_context_t is only used for logging and to get information about
the online state. */
pub type dc_imap_t = _dc_imap;
pub type dc_precheck_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
_: uint32_t,
) -> libc::c_int,
>;
pub type dc_set_config_t = Option<
unsafe extern "C" fn(_: *mut dc_imap_t, _: *const libc::c_char, _: *const libc::c_char) -> (),
>;
pub type dc_get_config_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
) -> *mut libc::c_char,
>;
/* ** library-private **********************************************************/
pub type dc_sqlite3_t = _dc_sqlite3;
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_sqlite3 {
pub cobj: *mut sqlite3,
pub context: *mut dc_context_t,
}
#[no_mangle]
pub unsafe extern "C" fn dc_log_event(
mut context: *mut dc_context_t,
mut event_code: libc::c_int,
mut data1: libc::c_int,
mut msg: *const libc::c_char,
mut va: ...
) {
log_vprintf(context, event_code, data1, msg, va);
}
/* Asynchronous "Thread-errors" are reported by the dc_log_error()
function. These errors must be shown to the user by a bubble or so.
"Normal" errors are usually returned by a special value (null or so) and are
usually not reported using dc_log_error() - its up to the caller to
decide, what should be reported or done. However, these "Normal" errors
are usually logged by dc_log_warning(). */
unsafe extern "C" fn log_vprintf(
mut context: *mut dc_context_t,
mut event: libc::c_int,
mut data1: libc::c_int,
mut msg_format: *const libc::c_char,
mut va_0: ::std::ffi::VaList,
) {
let mut msg: *mut libc::c_char = 0 as *mut libc::c_char;
if context.is_null() || (*context).magic != 0x11a11807i32 as libc::c_uint {
return;
}
if !msg_format.is_null() {
let mut tempbuf: [libc::c_char; 1025] = [0; 1025];
vsnprintf(
tempbuf.as_mut_ptr(),
1024i32 as libc::c_ulong,
msg_format,
va_0,
);
msg = dc_strdup(tempbuf.as_mut_ptr())
} else {
msg = dc_mprintf(
b"event #%i\x00" as *const u8 as *const libc::c_char,
event as libc::c_int,
)
}
(*context).cb.expect("non-null function pointer")(
context,
event,
data1 as uintptr_t,
msg as uintptr_t,
);
free(msg as *mut libc::c_void);
}
#[no_mangle]
pub unsafe extern "C" fn dc_log_event_seq(
mut context: *mut dc_context_t,
mut event_code: libc::c_int,
mut sequence_start: *mut libc::c_int,
mut msg: *const libc::c_char,
mut va_0: ...
) {
if context.is_null()
|| sequence_start.is_null()
|| (*context).magic != 0x11a11807i32 as libc::c_uint
{
return;
}
log_vprintf(context, event_code, *sequence_start, msg, va_0);
*sequence_start = 0i32;
}
#[no_mangle]
pub unsafe extern "C" fn dc_log_error(
mut context: *mut dc_context_t,
mut data1: libc::c_int,
mut msg: *const libc::c_char,
mut va_1: ...
) {
log_vprintf(context, 400i32, data1, msg, va_1);
}
#[no_mangle]
pub unsafe extern "C" fn dc_log_warning(
mut context: *mut dc_context_t,
mut data1: libc::c_int,
mut msg: *const libc::c_char,
mut va_2: ...
) {
log_vprintf(context, 300i32, data1, msg, va_2);
}
#[no_mangle]
pub unsafe extern "C" fn dc_log_info(
mut context: *mut dc_context_t,
mut data1: libc::c_int,
mut msg: *const libc::c_char,
mut va_3: ...
) {
log_vprintf(context, 100i32, data1, msg, va_3);
}

1153
src/dc_loginparam.rs Normal file

File diff suppressed because it is too large Load Diff

986
src/dc_lot.rs Normal file
View File

@@ -0,0 +1,986 @@
use c2rust_bitfields::BitfieldStruct;
use libc;
extern "C" {
pub type mailstream_cancel;
pub type sqlite3;
#[no_mangle]
fn calloc(_: libc::c_ulong, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn exit(_: libc::c_int) -> !;
#[no_mangle]
fn dc_chat_is_self_talk(_: *const dc_chat_t) -> libc::c_int;
#[no_mangle]
fn dc_msg_get_timestamp(_: *const dc_msg_t) -> time_t;
#[no_mangle]
fn dc_msg_is_info(_: *const dc_msg_t) -> libc::c_int;
#[no_mangle]
fn dc_contact_get_display_name(_: *const dc_contact_t) -> *mut libc::c_char;
#[no_mangle]
fn dc_contact_get_first_name(_: *const dc_contact_t) -> *mut libc::c_char;
#[no_mangle]
fn dc_strdup_keep_null(_: *const libc::c_char) -> *mut libc::c_char;
/* Return the string with the given ID by calling DC_EVENT_GET_STRING.
The result must be free()'d! */
#[no_mangle]
fn dc_stock_str(_: *mut dc_context_t, id: libc::c_int) -> *mut libc::c_char;
#[no_mangle]
fn dc_msg_get_summarytext_by_raw(
type_0: libc::c_int,
text: *const libc::c_char,
_: *mut dc_param_t,
approx_bytes: libc::c_int,
_: *mut dc_context_t,
) -> *mut libc::c_char;
}
pub type __darwin_size_t = libc::c_ulong;
pub type __darwin_ssize_t = libc::c_long;
pub type __darwin_time_t = libc::c_long;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_cond_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 40],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_mutex_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 56],
}
pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t;
pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t;
pub type uintptr_t = libc::c_ulong;
pub type size_t = __darwin_size_t;
pub type uint8_t = libc::c_uchar;
pub type uint32_t = libc::c_uint;
pub type ssize_t = __darwin_ssize_t;
pub type time_t = __darwin_time_t;
pub type pthread_cond_t = __darwin_pthread_cond_t;
pub type pthread_mutex_t = __darwin_pthread_mutex_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct carray_s {
pub array: *mut *mut libc::c_void,
pub len: libc::c_uint,
pub max: libc::c_uint,
}
pub type carray = carray_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream {
pub buffer_max_size: size_t,
pub write_buffer: *mut libc::c_char,
pub write_buffer_len: size_t,
pub read_buffer: *mut libc::c_char,
pub read_buffer_len: size_t,
pub low: *mut mailstream_low,
pub idle: *mut mailstream_cancel,
pub idling: libc::c_int,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
pub type mailstream = _mailstream;
pub type mailstream_low = _mailstream_low;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream_low {
pub data: *mut libc::c_void,
pub driver: *mut mailstream_low_driver,
pub privacy: libc::c_int,
pub identifier: *mut libc::c_char,
pub timeout: libc::c_ulong,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream_low,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailstream_low_driver {
pub mailstream_read: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *mut libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_write: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *const libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_close: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_get_fd: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_free: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_cancel: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_get_cancel:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut mailstream_cancel>,
pub mailstream_get_certificate_chain:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut carray>,
pub mailstream_setup_idle: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_unsetup_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_interrupt_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
}
pub type progress_function = unsafe extern "C" fn(_: size_t, _: size_t) -> ();
pub type mailprogress_function =
unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _MMAPString {
pub str_0: *mut libc::c_char,
pub len: size_t,
pub allocated_len: size_t,
pub fd: libc::c_int,
pub mmapped_size: size_t,
}
pub type MMAPString = _MMAPString;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clistcell_s {
pub data: *mut libc::c_void,
pub previous: *mut clistcell_s,
pub next: *mut clistcell_s,
}
pub type clistcell = clistcell_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clist_s {
pub first: *mut clistcell,
pub last: *mut clistcell,
pub count: libc::c_int,
}
pub type clist = clist_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailsmtp {
pub stream: *mut mailstream,
pub progr_rate: size_t,
pub progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub response: *mut libc::c_char,
pub line_buffer: *mut MMAPString,
pub response_buffer: *mut MMAPString,
pub esmtp: libc::c_int,
pub auth: libc::c_int,
pub smtp_sasl: unnamed,
pub smtp_max_msg_size: size_t,
pub smtp_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub smtp_progress_context: *mut libc::c_void,
pub response_code: libc::c_int,
pub smtp_timeout: time_t,
pub smtp_logger: Option<
unsafe extern "C" fn(
_: *mut mailsmtp,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub smtp_logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_capability_data {
pub cap_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att_body_section {
pub sec_section: *mut mailimap_section,
pub sec_origin_octet: uint32_t,
pub sec_body_part: *mut libc::c_char,
pub sec_length: size_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section {
pub sec_spec: *mut mailimap_section_spec,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_spec {
pub sec_type: libc::c_int,
pub sec_data: unnamed_0,
pub sec_text: *mut mailimap_section_text,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_text {
pub sec_type: libc::c_int,
pub sec_msgtext: *mut mailimap_section_msgtext,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_msgtext {
pub sec_type: libc::c_int,
pub sec_header_list: *mut mailimap_header_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_header_list {
pub hdr_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_0 {
pub sec_msgtext: *mut mailimap_section_msgtext,
pub sec_part: *mut mailimap_section_part,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_part {
pub sec_id: *mut clist,
}
pub type mailimap_msg_body_handler = unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_flag_list {
pub fl_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_mailbox_data_status {
pub st_mailbox: *mut libc::c_char,
pub st_info_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att {
pub att_list: *mut clist,
pub att_number: uint32_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_att {
pub att_type: libc::c_int,
pub att_section: *mut mailimap_section,
pub att_offset: uint32_t,
pub att_size: uint32_t,
pub att_extension: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_type {
pub ft_type: libc::c_int,
pub ft_data: unnamed_1,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_1 {
pub ft_fetch_att: *mut mailimap_fetch_att,
pub ft_fetch_att_list: *mut clist,
}
pub type mailimap_msg_att_handler =
unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap {
pub imap_response: *mut libc::c_char,
pub imap_stream: *mut mailstream,
pub imap_progr_rate: size_t,
pub imap_progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub imap_stream_buffer: *mut MMAPString,
pub imap_response_buffer: *mut MMAPString,
pub imap_state: libc::c_int,
pub imap_tag: libc::c_int,
pub imap_connection_info: *mut mailimap_connection_info,
pub imap_selection_info: *mut mailimap_selection_info,
pub imap_response_info: *mut mailimap_response_info,
pub imap_sasl: unnamed_2,
pub imap_idle_timestamp: time_t,
pub imap_idle_maxdelay: time_t,
pub imap_body_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_items_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_progress_context: *mut libc::c_void,
pub imap_msg_att_handler:
Option<unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ()>,
pub imap_msg_att_handler_context: *mut libc::c_void,
pub imap_msg_body_handler: Option<
unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool,
>,
pub imap_msg_body_handler_context: *mut libc::c_void,
pub imap_timeout: time_t,
pub imap_logger: Option<
unsafe extern "C" fn(
_: *mut mailimap,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub imap_logger_context: *mut libc::c_void,
pub is_163_workaround_enabled: libc::c_int,
pub is_rambler_workaround_enabled: libc::c_int,
pub is_qip_workaround_enabled: libc::c_int,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed_2 {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_response_info {
pub rsp_alert: *mut libc::c_char,
pub rsp_parse: *mut libc::c_char,
pub rsp_badcharset: *mut clist,
pub rsp_trycreate: libc::c_int,
pub rsp_mailbox_list: *mut clist,
pub rsp_mailbox_lsub: *mut clist,
pub rsp_search_result: *mut clist,
pub rsp_status: *mut mailimap_mailbox_data_status,
pub rsp_expunged: *mut clist,
pub rsp_fetch_list: *mut clist,
pub rsp_extension_list: *mut clist,
pub rsp_atom: *mut libc::c_char,
pub rsp_value: *mut libc::c_char,
}
#[derive(BitfieldStruct, Clone, Copy)]
#[repr(C)]
pub struct mailimap_selection_info {
pub sel_perm_flags: *mut clist,
pub sel_perm: libc::c_int,
pub sel_uidnext: uint32_t,
pub sel_uidvalidity: uint32_t,
pub sel_first_unseen: uint32_t,
pub sel_flags: *mut mailimap_flag_list,
pub sel_exists: uint32_t,
pub sel_recent: uint32_t,
pub sel_unseen: uint32_t,
#[bitfield(name = "sel_has_exists", ty = "uint8_t", bits = "0..=0")]
#[bitfield(name = "sel_has_recent", ty = "uint8_t", bits = "1..=1")]
pub sel_has_exists_sel_has_recent: [u8; 1],
pub _pad: [u8; 3],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_connection_info {
pub imap_capability: *mut mailimap_capability_data,
}
/* define DC_USE_RPGP to enable use of rPGP instead of netpgp where available;
preferrably, this should be done in the project configuration currently */
//#define DC_USE_RPGP 1
/* Includes that are used frequently. This file may also be used to create predefined headers. */
/* * Structure behind dc_context_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_context {
pub magic: uint32_t,
pub userdata: *mut libc::c_void,
pub dbfile: *mut libc::c_char,
pub blobdir: *mut libc::c_char,
pub sql: *mut dc_sqlite3_t,
pub inbox: *mut dc_imap_t,
pub inboxidle_condmutex: pthread_mutex_t,
pub perform_inbox_jobs_needed: libc::c_int,
pub probe_imap_network: libc::c_int,
pub sentbox_thread: dc_jobthread_t,
pub mvbox_thread: dc_jobthread_t,
pub smtp: *mut dc_smtp_t,
pub smtpidle_cond: pthread_cond_t,
pub smtpidle_condmutex: pthread_mutex_t,
pub smtpidle_condflag: libc::c_int,
pub smtp_suspended: libc::c_int,
pub smtp_doing_jobs: libc::c_int,
pub perform_smtp_jobs_needed: libc::c_int,
pub probe_smtp_network: libc::c_int,
pub oauth2_critical: pthread_mutex_t,
pub cb: dc_callback_t,
pub os_name: *mut libc::c_char,
pub cmdline_sel_chat_id: uint32_t,
pub bob_expects: libc::c_int,
pub bobs_status: libc::c_int,
pub bobs_qr_scan: *mut dc_lot_t,
pub bobs_qr_critical: pthread_mutex_t,
pub last_smeared_timestamp: time_t,
pub smear_critical: pthread_mutex_t,
pub ongoing_running: libc::c_int,
pub shall_stop_ongoing: libc::c_int,
}
pub type dc_lot_t = _dc_lot;
/* * Structure behind dc_lot_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_lot {
pub magic: uint32_t,
pub text1_meaning: libc::c_int,
pub text1: *mut libc::c_char,
pub text2: *mut libc::c_char,
pub timestamp: time_t,
pub state: libc::c_int,
pub id: uint32_t,
pub fingerprint: *mut libc::c_char,
pub invitenumber: *mut libc::c_char,
pub auth: *mut libc::c_char,
}
/* *
* Callback function that should be given to dc_context_new().
*
* @memberof dc_context_t
* @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 = Option<
unsafe extern "C" fn(
_: *mut dc_context_t,
_: libc::c_int,
_: uintptr_t,
_: uintptr_t,
) -> uintptr_t,
>;
/* *
* @mainpage Getting started
*
* This document describes how to handle the Delta Chat core library.
* For general information about Delta Chat itself,
* see <https://delta.chat> and <https://github.com/deltachat>.
*
* Let's start.
*
* First of all, you have to **define an event-handler-function**
* that is called by the library on specific events
* (eg. when the configuration is done or when fresh messages arrive).
* With this function you can create a Delta Chat context then:
*
* ~~~
* #include <deltachat.h>
*
* uintptr_t event_handler_func(dc_context_t* context, int event,
* uintptr_t data1, uintptr_t data2)
* {
* return 0; // for unhandled events, it is always safe to return 0
* }
*
* dc_context_t* context = dc_context_new(event_handler_func, NULL, NULL);
* ~~~
*
* After that, you should make sure,
* sending and receiving jobs are processed as needed.
* For this purpose, you have to **create two threads:**
*
* ~~~
* #include <pthread.h>
*
* void* imap_thread_func(void* context)
* {
* while (true) {
* dc_perform_imap_jobs(context);
* dc_perform_imap_fetch(context);
* dc_perform_imap_idle(context);
* }
* }
*
* void* smtp_thread_func(void* context)
* {
* while (true) {
* dc_perform_smtp_jobs(context);
* dc_perform_smtp_idle(context);
* }
* }
*
* static pthread_t imap_thread, smtp_thread;
* pthread_create(&imap_thread, NULL, imap_thread_func, context);
* pthread_create(&smtp_thread, NULL, smtp_thread_func, context);
* ~~~
*
* The example above uses "pthreads",
* however, you can also use anything else for thread handling.
* NB: The deltachat-core library itself does not create any threads on its own,
* however, functions, unless stated otherwise, are thread-safe.
*
* After that you can **define and open a database.**
* The database is a normal sqlite-file and is created as needed:
*
* ~~~
* dc_open(context, "example.db", NULL);
* ~~~
*
* Now you can **configure the context:**
*
* ~~~
* // use some real test credentials here
* dc_set_config(context, "addr", "alice@example.org");
* dc_set_config(context, "mail_pw", "***");
* dc_configure(context);
* ~~~
*
* dc_configure() returns immediately, the configuration itself may take a while
* and is done by a job in the imap-thread you've defined above.
* Once done, the #DC_EVENT_CONFIGURE_PROGRESS reports success
* to the event_handler_func() that is also defined above.
*
* The configuration result is saved in the database,
* on subsequent starts it is not needed to call dc_configure()
* (you can check this using dc_is_configured()).
*
* Now you can **send the first message:**
*
* ~~~
* // use a real testing address here
* uint32_t contact_id = dc_create_contact(context, NULL, "bob@example.org");
* uint32_t chat_id = dc_create_chat_by_contact_id(context, contact_id);
*
* dc_send_text_msg(context, chat_id, "Hi, here is my first message!");
* ~~~
*
* dc_send_text_msg() returns immediately;
* the sending itself is done by a job in the smtp-thread you've defined above.
* If you check the testing address (bob)
* and you should have received a normal email.
* Answer this email in any email program with "Got it!"
* and the imap-thread you've create above will **receive the message**.
*
* You can then **list all messages** of a chat as follow:
*
* ~~~
* dc_array_t* msglist = dc_get_chat_msgs(context, chat_id, 0, 0);
* for (int i = 0; i < dc_array_get_cnt(msglist); i++)
* {
* uint32_t msg_id = dc_array_get_id(msglist, i);
* dc_msg_t* msg = dc_get_msg(context, msg_id);
* char* text = dc_msg_get_text(msg);
*
* printf("Message %i: %s\n", i+1, text);
*
* free(text);
* dc_msg_unref(msg);
* }
* dc_array_unref(msglist);
* ~~~
*
* This will output the following two lines:
*
* ~~~
* Message 1: Hi, here is my first message!
* Message 2: Got it!
* ~~~
*
*
* ## Class reference
*
* For a class reference, see the "Classes" link atop.
*
*
* ## Further hints
*
* Here are some additional, unsorted hints that may be useful.
*
* - For `get`-functions, you have to unref the return value in some way.
*
* - Strings in function arguments or return values are usually UTF-8 encoded.
*
* - The issue-tracker for the core library is here:
* <https://github.com/deltachat/deltachat-core/issues>
*
* The following points are important mainly
* for the authors of the library itself:
*
* - For indentation, use tabs.
* Alignments that are not placed at the beginning of a line
* should be done with spaces.
*
* - For padding between functions,
* classes etc. use 2 empty lines
*
* - Source files are encoded as UTF-8 with Unix line endings
* (a simple `LF`, `0x0A` or `\n`)
*
* If you need further assistance,
* please do not hesitate to contact us
* through the channels shown at https://delta.chat/en/contribute
*
* Please keep in mind, that your derived work
* must respect the Mozilla Public License 2.0 of libdeltachat
* and the respective licenses of the libraries libdeltachat links with.
*
* See you.
*/
/* *
* @class dc_context_t
*
* An object representing a single account.
*
* Each account is linked to an IMAP/SMTP account and uses a separate
* SQLite database for offline functionality and for account-related
* settings.
*/
pub type dc_context_t = _dc_context;
/* ** library-private **********************************************************/
pub type dc_smtp_t = _dc_smtp;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_smtp {
pub etpan: *mut mailsmtp,
pub from: *mut libc::c_char,
pub esmtp: libc::c_int,
pub log_connect_errors: libc::c_int,
pub context: *mut dc_context_t,
pub error: *mut libc::c_char,
pub error_etpan: libc::c_int,
}
pub type dc_jobthread_t = _dc_jobthread;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_jobthread {
pub context: *mut dc_context_t,
pub name: *mut libc::c_char,
pub folder_config_name: *mut libc::c_char,
pub imap: *mut _dc_imap,
pub mutex: pthread_mutex_t,
pub idle_cond: pthread_cond_t,
pub idle_condflag: libc::c_int,
pub jobs_needed: libc::c_int,
pub suspended: libc::c_int,
pub using_handle: libc::c_int,
}
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_imap {
pub addr: *mut libc::c_char,
pub imap_server: *mut libc::c_char,
pub imap_port: libc::c_int,
pub imap_user: *mut libc::c_char,
pub imap_pw: *mut libc::c_char,
pub server_flags: libc::c_int,
pub connected: libc::c_int,
pub etpan: *mut mailimap,
pub idle_set_up: libc::c_int,
pub selected_folder: *mut libc::c_char,
pub selected_folder_needs_expunge: libc::c_int,
pub should_reconnect: libc::c_int,
pub can_idle: libc::c_int,
pub has_xlist: libc::c_int,
pub imap_delimiter: libc::c_char,
pub watch_folder: *mut libc::c_char,
pub watch_cond: pthread_cond_t,
pub watch_condmutex: pthread_mutex_t,
pub watch_condflag: libc::c_int,
pub fetch_type_prefetch: *mut mailimap_fetch_type,
pub fetch_type_body: *mut mailimap_fetch_type,
pub fetch_type_flags: *mut mailimap_fetch_type,
pub get_config: dc_get_config_t,
pub set_config: dc_set_config_t,
pub precheck_imf: dc_precheck_imf_t,
pub receive_imf: dc_receive_imf_t,
pub userData: *mut libc::c_void,
pub context: *mut dc_context_t,
pub log_connect_errors: libc::c_int,
pub skip_log_capabilities: libc::c_int,
}
pub type dc_receive_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: size_t,
_: *const libc::c_char,
_: uint32_t,
_: uint32_t,
) -> (),
>;
/* Purpose: Reading from IMAP servers with no dependencies to the database.
dc_context_t is only used for logging and to get information about
the online state. */
pub type dc_imap_t = _dc_imap;
pub type dc_precheck_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
_: uint32_t,
) -> libc::c_int,
>;
pub type dc_set_config_t = Option<
unsafe extern "C" fn(_: *mut dc_imap_t, _: *const libc::c_char, _: *const libc::c_char) -> (),
>;
pub type dc_get_config_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
) -> *mut libc::c_char,
>;
/* ** library-private **********************************************************/
pub type dc_sqlite3_t = _dc_sqlite3;
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_sqlite3 {
pub cobj: *mut sqlite3,
pub context: *mut dc_context_t,
}
/* values for the chats.blocked database field */
/* * the structure behind dc_chat_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_chat {
pub magic: uint32_t,
pub id: uint32_t,
pub type_0: libc::c_int,
pub name: *mut libc::c_char,
pub archived: libc::c_int,
pub context: *mut dc_context_t,
pub grpid: *mut libc::c_char,
pub blocked: libc::c_int,
pub param: *mut dc_param_t,
pub gossiped_timestamp: time_t,
pub is_sending_locations: libc::c_int,
}
pub type dc_param_t = _dc_param;
/* *
* @class dc_param_t
*
* An object for handling key=value parameter lists; for the key, curently only
* a single character is allowed.
*
* The object is used eg. by dc_chat_t or dc_msg_t, for readable paramter names,
* these classes define some DC_PARAM_* constantats.
*
* Only for library-internal use.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_param {
pub packed: *mut libc::c_char,
}
pub type dc_chat_t = _dc_chat;
/* * the structure behind dc_msg_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_msg {
pub magic: uint32_t,
pub id: uint32_t,
pub from_id: uint32_t,
pub to_id: uint32_t,
pub chat_id: uint32_t,
pub move_state: dc_move_state_t,
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 text: *mut libc::c_char,
pub context: *mut dc_context_t,
pub rfc724_mid: *mut libc::c_char,
pub in_reply_to: *mut libc::c_char,
pub server_folder: *mut libc::c_char,
pub server_uid: uint32_t,
pub is_dc_message: libc::c_int,
pub starred: libc::c_int,
pub chat_blocked: libc::c_int,
pub location_id: uint32_t,
pub param: *mut dc_param_t,
}
pub type dc_move_state_t = libc::c_uint;
pub const DC_MOVE_STATE_MOVING: dc_move_state_t = 3;
pub const DC_MOVE_STATE_STAY: dc_move_state_t = 2;
pub const DC_MOVE_STATE_PENDING: dc_move_state_t = 1;
pub const DC_MOVE_STATE_UNDEFINED: dc_move_state_t = 0;
pub type dc_msg_t = _dc_msg;
/* * the structure behind dc_contact_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_contact {
pub magic: uint32_t,
pub context: *mut dc_context_t,
pub id: uint32_t,
pub name: *mut libc::c_char,
pub authname: *mut libc::c_char,
pub addr: *mut libc::c_char,
pub blocked: libc::c_int,
pub origin: libc::c_int,
}
pub type dc_contact_t = _dc_contact;
/* *
* @class dc_lot_t
*
* An object containing a set of values.
* The meaning of the values is defined by the function returning the object.
* Lot objects are created
* eg. by dc_chatlist_get_summary() or dc_msg_get_summary().
*
* NB: _Lot_ is used in the meaning _heap_ here.
*/
#[no_mangle]
pub unsafe extern "C" fn dc_lot_new() -> *mut dc_lot_t {
let mut lot: *mut dc_lot_t = 0 as *mut dc_lot_t;
lot = calloc(
1i32 as libc::c_ulong,
::std::mem::size_of::<dc_lot_t>() as libc::c_ulong,
) as *mut dc_lot_t;
if lot.is_null() {
exit(27i32);
}
(*lot).magic = 0x107107i32 as uint32_t;
(*lot).text1_meaning = 0i32;
return lot;
}
#[no_mangle]
pub unsafe extern "C" fn dc_lot_empty(mut lot: *mut dc_lot_t) {
if lot.is_null() || (*lot).magic != 0x107107i32 as libc::c_uint {
return;
}
free((*lot).text1 as *mut libc::c_void);
(*lot).text1 = 0 as *mut libc::c_char;
(*lot).text1_meaning = 0i32;
free((*lot).text2 as *mut libc::c_void);
(*lot).text2 = 0 as *mut libc::c_char;
free((*lot).fingerprint as *mut libc::c_void);
(*lot).fingerprint = 0 as *mut libc::c_char;
free((*lot).invitenumber as *mut libc::c_void);
(*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).state = 0i32;
(*lot).id = 0i32 as uint32_t;
}
#[no_mangle]
pub unsafe extern "C" fn dc_lot_unref(mut set: *mut dc_lot_t) {
if set.is_null() || (*set).magic != 0x107107i32 as libc::c_uint {
return;
}
dc_lot_empty(set);
(*set).magic = 0i32 as uint32_t;
free(set as *mut libc::c_void);
}
#[no_mangle]
pub unsafe extern "C" fn dc_lot_get_text1(mut lot: *const dc_lot_t) -> *mut libc::c_char {
if lot.is_null() || (*lot).magic != 0x107107i32 as libc::c_uint {
return 0 as *mut libc::c_char;
}
return dc_strdup_keep_null((*lot).text1);
}
#[no_mangle]
pub unsafe extern "C" fn dc_lot_get_text2(mut lot: *const dc_lot_t) -> *mut libc::c_char {
if lot.is_null() || (*lot).magic != 0x107107i32 as libc::c_uint {
return 0 as *mut libc::c_char;
}
return dc_strdup_keep_null((*lot).text2);
}
#[no_mangle]
pub unsafe extern "C" fn dc_lot_get_text1_meaning(mut lot: *const dc_lot_t) -> libc::c_int {
if lot.is_null() || (*lot).magic != 0x107107i32 as libc::c_uint {
return 0i32;
}
return (*lot).text1_meaning;
}
#[no_mangle]
pub unsafe extern "C" fn dc_lot_get_state(mut lot: *const dc_lot_t) -> libc::c_int {
if lot.is_null() || (*lot).magic != 0x107107i32 as libc::c_uint {
return 0i32;
}
return (*lot).state;
}
#[no_mangle]
pub unsafe extern "C" fn dc_lot_get_id(mut lot: *const dc_lot_t) -> uint32_t {
if lot.is_null() || (*lot).magic != 0x107107i32 as libc::c_uint {
return 0i32 as uint32_t;
}
return (*lot).id;
}
#[no_mangle]
pub unsafe extern "C" fn dc_lot_get_timestamp(mut lot: *const dc_lot_t) -> time_t {
if lot.is_null() || (*lot).magic != 0x107107i32 as libc::c_uint {
return 0i32 as time_t;
}
return (*lot).timestamp;
}
/* library-internal */
/* in practice, the user additionally cuts the string himself pixel-accurate */
#[no_mangle]
pub unsafe extern "C" fn dc_lot_fill(
mut lot: *mut dc_lot_t,
mut msg: *const dc_msg_t,
mut chat: *const dc_chat_t,
mut contact: *const dc_contact_t,
mut context: *mut dc_context_t,
) {
if lot.is_null() || (*lot).magic != 0x107107i32 as libc::c_uint || msg.is_null() {
return;
}
if (*msg).state == 19i32 {
(*lot).text1 = dc_stock_str(context, 3i32);
(*lot).text1_meaning = 1i32
} else if (*msg).from_id == 1i32 as libc::c_uint {
if 0 != dc_msg_is_info(msg) || 0 != dc_chat_is_self_talk(chat) {
(*lot).text1 = 0 as *mut libc::c_char;
(*lot).text1_meaning = 0i32
} else {
(*lot).text1 = dc_stock_str(context, 2i32);
(*lot).text1_meaning = 3i32
}
} else if chat.is_null() {
(*lot).text1 = 0 as *mut libc::c_char;
(*lot).text1_meaning = 0i32
} else if (*chat).type_0 == 120i32 || (*chat).type_0 == 130i32 {
if 0 != dc_msg_is_info(msg) || contact.is_null() {
(*lot).text1 = 0 as *mut libc::c_char;
(*lot).text1_meaning = 0i32
} else {
if !chat.is_null() && (*chat).id == 1i32 as libc::c_uint {
(*lot).text1 = dc_contact_get_display_name(contact)
} else {
(*lot).text1 = dc_contact_get_first_name(contact)
}
(*lot).text1_meaning = 2i32
}
}
(*lot).text2 =
dc_msg_get_summarytext_by_raw((*msg).type_0, (*msg).text, (*msg).param, 160i32, context);
(*lot).timestamp = dc_msg_get_timestamp(msg);
(*lot).state = (*msg).state;
}

2920
src/dc_mimefactory.rs Normal file

File diff suppressed because it is too large Load Diff

3428
src/dc_mimeparser.rs Normal file

File diff suppressed because it is too large Load Diff

858
src/dc_move.rs Normal file
View File

@@ -0,0 +1,858 @@
use c2rust_bitfields::BitfieldStruct;
use libc;
extern "C" {
pub type mailstream_cancel;
pub type sqlite3;
pub type sqlite3_stmt;
#[no_mangle]
fn dc_msg_unref(_: *mut dc_msg_t);
#[no_mangle]
fn dc_msg_is_setupmessage(_: *const dc_msg_t) -> libc::c_int;
#[no_mangle]
fn sqlite3_finalize(pStmt: *mut sqlite3_stmt) -> libc::c_int;
#[no_mangle]
fn dc_sqlite3_get_config_int(
_: *mut dc_sqlite3_t,
key: *const libc::c_char,
def: int32_t,
) -> int32_t;
#[no_mangle]
fn dc_msg_new_load(_: *mut dc_context_t, id: uint32_t) -> *mut dc_msg_t;
#[no_mangle]
fn dc_update_msg_move_state(
_: *mut dc_context_t,
rfc724_mid: *const libc::c_char,
_: dc_move_state_t,
);
#[no_mangle]
fn dc_job_add(
_: *mut dc_context_t,
action: libc::c_int,
foreign_id: libc::c_int,
param: *const libc::c_char,
delay: libc::c_int,
);
#[no_mangle]
fn dc_is_mvbox(_: *mut dc_context_t, folder: *const libc::c_char) -> libc::c_int;
#[no_mangle]
fn dc_is_sentbox(_: *mut dc_context_t, folder: *const libc::c_char) -> libc::c_int;
#[no_mangle]
fn dc_is_inbox(_: *mut dc_context_t, folder: *const libc::c_char) -> libc::c_int;
}
pub type __darwin_size_t = libc::c_ulong;
pub type __darwin_ssize_t = libc::c_long;
pub type __darwin_time_t = libc::c_long;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_cond_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 40],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_mutex_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 56],
}
pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t;
pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t;
pub type int32_t = libc::c_int;
pub type uintptr_t = libc::c_ulong;
pub type size_t = __darwin_size_t;
pub type uint8_t = libc::c_uchar;
pub type uint32_t = libc::c_uint;
pub type ssize_t = __darwin_ssize_t;
pub type time_t = __darwin_time_t;
pub type pthread_cond_t = __darwin_pthread_cond_t;
pub type pthread_mutex_t = __darwin_pthread_mutex_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct carray_s {
pub array: *mut *mut libc::c_void,
pub len: libc::c_uint,
pub max: libc::c_uint,
}
pub type carray = carray_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream {
pub buffer_max_size: size_t,
pub write_buffer: *mut libc::c_char,
pub write_buffer_len: size_t,
pub read_buffer: *mut libc::c_char,
pub read_buffer_len: size_t,
pub low: *mut mailstream_low,
pub idle: *mut mailstream_cancel,
pub idling: libc::c_int,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
pub type mailstream = _mailstream;
pub type mailstream_low = _mailstream_low;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream_low {
pub data: *mut libc::c_void,
pub driver: *mut mailstream_low_driver,
pub privacy: libc::c_int,
pub identifier: *mut libc::c_char,
pub timeout: libc::c_ulong,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream_low,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailstream_low_driver {
pub mailstream_read: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *mut libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_write: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *const libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_close: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_get_fd: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_free: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_cancel: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_get_cancel:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut mailstream_cancel>,
pub mailstream_get_certificate_chain:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut carray>,
pub mailstream_setup_idle: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_unsetup_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_interrupt_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
}
pub type progress_function = unsafe extern "C" fn(_: size_t, _: size_t) -> ();
pub type mailprogress_function =
unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _MMAPString {
pub str_0: *mut libc::c_char,
pub len: size_t,
pub allocated_len: size_t,
pub fd: libc::c_int,
pub mmapped_size: size_t,
}
pub type MMAPString = _MMAPString;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clistcell_s {
pub data: *mut libc::c_void,
pub previous: *mut clistcell_s,
pub next: *mut clistcell_s,
}
pub type clistcell = clistcell_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clist_s {
pub first: *mut clistcell,
pub last: *mut clistcell,
pub count: libc::c_int,
}
pub type clist = clist_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailsmtp {
pub stream: *mut mailstream,
pub progr_rate: size_t,
pub progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub response: *mut libc::c_char,
pub line_buffer: *mut MMAPString,
pub response_buffer: *mut MMAPString,
pub esmtp: libc::c_int,
pub auth: libc::c_int,
pub smtp_sasl: unnamed,
pub smtp_max_msg_size: size_t,
pub smtp_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub smtp_progress_context: *mut libc::c_void,
pub response_code: libc::c_int,
pub smtp_timeout: time_t,
pub smtp_logger: Option<
unsafe extern "C" fn(
_: *mut mailsmtp,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub smtp_logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_capability_data {
pub cap_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att_body_section {
pub sec_section: *mut mailimap_section,
pub sec_origin_octet: uint32_t,
pub sec_body_part: *mut libc::c_char,
pub sec_length: size_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section {
pub sec_spec: *mut mailimap_section_spec,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_spec {
pub sec_type: libc::c_int,
pub sec_data: unnamed_0,
pub sec_text: *mut mailimap_section_text,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_text {
pub sec_type: libc::c_int,
pub sec_msgtext: *mut mailimap_section_msgtext,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_msgtext {
pub sec_type: libc::c_int,
pub sec_header_list: *mut mailimap_header_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_header_list {
pub hdr_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_0 {
pub sec_msgtext: *mut mailimap_section_msgtext,
pub sec_part: *mut mailimap_section_part,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_part {
pub sec_id: *mut clist,
}
pub type mailimap_msg_body_handler = unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_flag_list {
pub fl_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_mailbox_data_status {
pub st_mailbox: *mut libc::c_char,
pub st_info_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att {
pub att_list: *mut clist,
pub att_number: uint32_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_att {
pub att_type: libc::c_int,
pub att_section: *mut mailimap_section,
pub att_offset: uint32_t,
pub att_size: uint32_t,
pub att_extension: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_type {
pub ft_type: libc::c_int,
pub ft_data: unnamed_1,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_1 {
pub ft_fetch_att: *mut mailimap_fetch_att,
pub ft_fetch_att_list: *mut clist,
}
pub type mailimap_msg_att_handler =
unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap {
pub imap_response: *mut libc::c_char,
pub imap_stream: *mut mailstream,
pub imap_progr_rate: size_t,
pub imap_progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub imap_stream_buffer: *mut MMAPString,
pub imap_response_buffer: *mut MMAPString,
pub imap_state: libc::c_int,
pub imap_tag: libc::c_int,
pub imap_connection_info: *mut mailimap_connection_info,
pub imap_selection_info: *mut mailimap_selection_info,
pub imap_response_info: *mut mailimap_response_info,
pub imap_sasl: unnamed_2,
pub imap_idle_timestamp: time_t,
pub imap_idle_maxdelay: time_t,
pub imap_body_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_items_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_progress_context: *mut libc::c_void,
pub imap_msg_att_handler:
Option<unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ()>,
pub imap_msg_att_handler_context: *mut libc::c_void,
pub imap_msg_body_handler: Option<
unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool,
>,
pub imap_msg_body_handler_context: *mut libc::c_void,
pub imap_timeout: time_t,
pub imap_logger: Option<
unsafe extern "C" fn(
_: *mut mailimap,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub imap_logger_context: *mut libc::c_void,
pub is_163_workaround_enabled: libc::c_int,
pub is_rambler_workaround_enabled: libc::c_int,
pub is_qip_workaround_enabled: libc::c_int,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed_2 {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_response_info {
pub rsp_alert: *mut libc::c_char,
pub rsp_parse: *mut libc::c_char,
pub rsp_badcharset: *mut clist,
pub rsp_trycreate: libc::c_int,
pub rsp_mailbox_list: *mut clist,
pub rsp_mailbox_lsub: *mut clist,
pub rsp_search_result: *mut clist,
pub rsp_status: *mut mailimap_mailbox_data_status,
pub rsp_expunged: *mut clist,
pub rsp_fetch_list: *mut clist,
pub rsp_extension_list: *mut clist,
pub rsp_atom: *mut libc::c_char,
pub rsp_value: *mut libc::c_char,
}
#[derive(BitfieldStruct, Clone, Copy)]
#[repr(C)]
pub struct mailimap_selection_info {
pub sel_perm_flags: *mut clist,
pub sel_perm: libc::c_int,
pub sel_uidnext: uint32_t,
pub sel_uidvalidity: uint32_t,
pub sel_first_unseen: uint32_t,
pub sel_flags: *mut mailimap_flag_list,
pub sel_exists: uint32_t,
pub sel_recent: uint32_t,
pub sel_unseen: uint32_t,
#[bitfield(name = "sel_has_exists", ty = "uint8_t", bits = "0..=0")]
#[bitfield(name = "sel_has_recent", ty = "uint8_t", bits = "1..=1")]
pub sel_has_exists_sel_has_recent: [u8; 1],
pub _pad: [u8; 3],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_connection_info {
pub imap_capability: *mut mailimap_capability_data,
}
/* define DC_USE_RPGP to enable use of rPGP instead of netpgp where available;
preferrably, this should be done in the project configuration currently */
//#define DC_USE_RPGP 1
/* Includes that are used frequently. This file may also be used to create predefined headers. */
/* * Structure behind dc_context_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_context {
pub magic: uint32_t,
pub userdata: *mut libc::c_void,
pub dbfile: *mut libc::c_char,
pub blobdir: *mut libc::c_char,
pub sql: *mut dc_sqlite3_t,
pub inbox: *mut dc_imap_t,
pub inboxidle_condmutex: pthread_mutex_t,
pub perform_inbox_jobs_needed: libc::c_int,
pub probe_imap_network: libc::c_int,
pub sentbox_thread: dc_jobthread_t,
pub mvbox_thread: dc_jobthread_t,
pub smtp: *mut dc_smtp_t,
pub smtpidle_cond: pthread_cond_t,
pub smtpidle_condmutex: pthread_mutex_t,
pub smtpidle_condflag: libc::c_int,
pub smtp_suspended: libc::c_int,
pub smtp_doing_jobs: libc::c_int,
pub perform_smtp_jobs_needed: libc::c_int,
pub probe_smtp_network: libc::c_int,
pub oauth2_critical: pthread_mutex_t,
pub cb: dc_callback_t,
pub os_name: *mut libc::c_char,
pub cmdline_sel_chat_id: uint32_t,
pub bob_expects: libc::c_int,
pub bobs_status: libc::c_int,
pub bobs_qr_scan: *mut dc_lot_t,
pub bobs_qr_critical: pthread_mutex_t,
pub last_smeared_timestamp: time_t,
pub smear_critical: pthread_mutex_t,
pub ongoing_running: libc::c_int,
pub shall_stop_ongoing: libc::c_int,
}
pub type dc_lot_t = _dc_lot;
/* * Structure behind dc_lot_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_lot {
pub magic: uint32_t,
pub text1_meaning: libc::c_int,
pub text1: *mut libc::c_char,
pub text2: *mut libc::c_char,
pub timestamp: time_t,
pub state: libc::c_int,
pub id: uint32_t,
pub fingerprint: *mut libc::c_char,
pub invitenumber: *mut libc::c_char,
pub auth: *mut libc::c_char,
}
/* *
* Callback function that should be given to dc_context_new().
*
* @memberof dc_context_t
* @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 = Option<
unsafe extern "C" fn(
_: *mut dc_context_t,
_: libc::c_int,
_: uintptr_t,
_: uintptr_t,
) -> uintptr_t,
>;
/* *
* @mainpage Getting started
*
* This document describes how to handle the Delta Chat core library.
* For general information about Delta Chat itself,
* see <https://delta.chat> and <https://github.com/deltachat>.
*
* Let's start.
*
* First of all, you have to **define an event-handler-function**
* that is called by the library on specific events
* (eg. when the configuration is done or when fresh messages arrive).
* With this function you can create a Delta Chat context then:
*
* ~~~
* #include <deltachat.h>
*
* uintptr_t event_handler_func(dc_context_t* context, int event,
* uintptr_t data1, uintptr_t data2)
* {
* return 0; // for unhandled events, it is always safe to return 0
* }
*
* dc_context_t* context = dc_context_new(event_handler_func, NULL, NULL);
* ~~~
*
* After that, you should make sure,
* sending and receiving jobs are processed as needed.
* For this purpose, you have to **create two threads:**
*
* ~~~
* #include <pthread.h>
*
* void* imap_thread_func(void* context)
* {
* while (true) {
* dc_perform_imap_jobs(context);
* dc_perform_imap_fetch(context);
* dc_perform_imap_idle(context);
* }
* }
*
* void* smtp_thread_func(void* context)
* {
* while (true) {
* dc_perform_smtp_jobs(context);
* dc_perform_smtp_idle(context);
* }
* }
*
* static pthread_t imap_thread, smtp_thread;
* pthread_create(&imap_thread, NULL, imap_thread_func, context);
* pthread_create(&smtp_thread, NULL, smtp_thread_func, context);
* ~~~
*
* The example above uses "pthreads",
* however, you can also use anything else for thread handling.
* NB: The deltachat-core library itself does not create any threads on its own,
* however, functions, unless stated otherwise, are thread-safe.
*
* After that you can **define and open a database.**
* The database is a normal sqlite-file and is created as needed:
*
* ~~~
* dc_open(context, "example.db", NULL);
* ~~~
*
* Now you can **configure the context:**
*
* ~~~
* // use some real test credentials here
* dc_set_config(context, "addr", "alice@example.org");
* dc_set_config(context, "mail_pw", "***");
* dc_configure(context);
* ~~~
*
* dc_configure() returns immediately, the configuration itself may take a while
* and is done by a job in the imap-thread you've defined above.
* Once done, the #DC_EVENT_CONFIGURE_PROGRESS reports success
* to the event_handler_func() that is also defined above.
*
* The configuration result is saved in the database,
* on subsequent starts it is not needed to call dc_configure()
* (you can check this using dc_is_configured()).
*
* Now you can **send the first message:**
*
* ~~~
* // use a real testing address here
* uint32_t contact_id = dc_create_contact(context, NULL, "bob@example.org");
* uint32_t chat_id = dc_create_chat_by_contact_id(context, contact_id);
*
* dc_send_text_msg(context, chat_id, "Hi, here is my first message!");
* ~~~
*
* dc_send_text_msg() returns immediately;
* the sending itself is done by a job in the smtp-thread you've defined above.
* If you check the testing address (bob)
* and you should have received a normal email.
* Answer this email in any email program with "Got it!"
* and the imap-thread you've create above will **receive the message**.
*
* You can then **list all messages** of a chat as follow:
*
* ~~~
* dc_array_t* msglist = dc_get_chat_msgs(context, chat_id, 0, 0);
* for (int i = 0; i < dc_array_get_cnt(msglist); i++)
* {
* uint32_t msg_id = dc_array_get_id(msglist, i);
* dc_msg_t* msg = dc_get_msg(context, msg_id);
* char* text = dc_msg_get_text(msg);
*
* printf("Message %i: %s\n", i+1, text);
*
* free(text);
* dc_msg_unref(msg);
* }
* dc_array_unref(msglist);
* ~~~
*
* This will output the following two lines:
*
* ~~~
* Message 1: Hi, here is my first message!
* Message 2: Got it!
* ~~~
*
*
* ## Class reference
*
* For a class reference, see the "Classes" link atop.
*
*
* ## Further hints
*
* Here are some additional, unsorted hints that may be useful.
*
* - For `get`-functions, you have to unref the return value in some way.
*
* - Strings in function arguments or return values are usually UTF-8 encoded.
*
* - The issue-tracker for the core library is here:
* <https://github.com/deltachat/deltachat-core/issues>
*
* The following points are important mainly
* for the authors of the library itself:
*
* - For indentation, use tabs.
* Alignments that are not placed at the beginning of a line
* should be done with spaces.
*
* - For padding between functions,
* classes etc. use 2 empty lines
*
* - Source files are encoded as UTF-8 with Unix line endings
* (a simple `LF`, `0x0A` or `\n`)
*
* If you need further assistance,
* please do not hesitate to contact us
* through the channels shown at https://delta.chat/en/contribute
*
* Please keep in mind, that your derived work
* must respect the Mozilla Public License 2.0 of libdeltachat
* and the respective licenses of the libraries libdeltachat links with.
*
* See you.
*/
/* *
* @class dc_context_t
*
* An object representing a single account.
*
* Each account is linked to an IMAP/SMTP account and uses a separate
* SQLite database for offline functionality and for account-related
* settings.
*/
pub type dc_context_t = _dc_context;
/* ** library-private **********************************************************/
pub type dc_smtp_t = _dc_smtp;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_smtp {
pub etpan: *mut mailsmtp,
pub from: *mut libc::c_char,
pub esmtp: libc::c_int,
pub log_connect_errors: libc::c_int,
pub context: *mut dc_context_t,
pub error: *mut libc::c_char,
pub error_etpan: libc::c_int,
}
pub type dc_jobthread_t = _dc_jobthread;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_jobthread {
pub context: *mut dc_context_t,
pub name: *mut libc::c_char,
pub folder_config_name: *mut libc::c_char,
pub imap: *mut _dc_imap,
pub mutex: pthread_mutex_t,
pub idle_cond: pthread_cond_t,
pub idle_condflag: libc::c_int,
pub jobs_needed: libc::c_int,
pub suspended: libc::c_int,
pub using_handle: libc::c_int,
}
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_imap {
pub addr: *mut libc::c_char,
pub imap_server: *mut libc::c_char,
pub imap_port: libc::c_int,
pub imap_user: *mut libc::c_char,
pub imap_pw: *mut libc::c_char,
pub server_flags: libc::c_int,
pub connected: libc::c_int,
pub etpan: *mut mailimap,
pub idle_set_up: libc::c_int,
pub selected_folder: *mut libc::c_char,
pub selected_folder_needs_expunge: libc::c_int,
pub should_reconnect: libc::c_int,
pub can_idle: libc::c_int,
pub has_xlist: libc::c_int,
pub imap_delimiter: libc::c_char,
pub watch_folder: *mut libc::c_char,
pub watch_cond: pthread_cond_t,
pub watch_condmutex: pthread_mutex_t,
pub watch_condflag: libc::c_int,
pub fetch_type_prefetch: *mut mailimap_fetch_type,
pub fetch_type_body: *mut mailimap_fetch_type,
pub fetch_type_flags: *mut mailimap_fetch_type,
pub get_config: dc_get_config_t,
pub set_config: dc_set_config_t,
pub precheck_imf: dc_precheck_imf_t,
pub receive_imf: dc_receive_imf_t,
pub userData: *mut libc::c_void,
pub context: *mut dc_context_t,
pub log_connect_errors: libc::c_int,
pub skip_log_capabilities: libc::c_int,
}
pub type dc_receive_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: size_t,
_: *const libc::c_char,
_: uint32_t,
_: uint32_t,
) -> (),
>;
/* Purpose: Reading from IMAP servers with no dependencies to the database.
dc_context_t is only used for logging and to get information about
the online state. */
pub type dc_imap_t = _dc_imap;
pub type dc_precheck_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
_: uint32_t,
) -> libc::c_int,
>;
pub type dc_set_config_t = Option<
unsafe extern "C" fn(_: *mut dc_imap_t, _: *const libc::c_char, _: *const libc::c_char) -> (),
>;
pub type dc_get_config_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
) -> *mut libc::c_char,
>;
/* ** library-private **********************************************************/
pub type dc_sqlite3_t = _dc_sqlite3;
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_sqlite3 {
pub cobj: *mut sqlite3,
pub context: *mut dc_context_t,
}
pub type dc_param_t = _dc_param;
/* *
* @class dc_param_t
*
* An object for handling key=value parameter lists; for the key, curently only
* a single character is allowed.
*
* The object is used eg. by dc_chat_t or dc_msg_t, for readable paramter names,
* these classes define some DC_PARAM_* constantats.
*
* Only for library-internal use.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_param {
pub packed: *mut libc::c_char,
}
/* * the structure behind dc_msg_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_msg {
pub magic: uint32_t,
pub id: uint32_t,
pub from_id: uint32_t,
pub to_id: uint32_t,
pub chat_id: uint32_t,
pub move_state: dc_move_state_t,
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 text: *mut libc::c_char,
pub context: *mut dc_context_t,
pub rfc724_mid: *mut libc::c_char,
pub in_reply_to: *mut libc::c_char,
pub server_folder: *mut libc::c_char,
pub server_uid: uint32_t,
pub is_dc_message: libc::c_int,
pub starred: libc::c_int,
pub chat_blocked: libc::c_int,
pub location_id: uint32_t,
pub param: *mut dc_param_t,
}
pub type dc_move_state_t = libc::c_uint;
pub const DC_MOVE_STATE_MOVING: dc_move_state_t = 3;
pub const DC_MOVE_STATE_STAY: dc_move_state_t = 2;
pub const DC_MOVE_STATE_PENDING: dc_move_state_t = 1;
pub const DC_MOVE_STATE_UNDEFINED: dc_move_state_t = 0;
pub type dc_msg_t = _dc_msg;
#[no_mangle]
pub unsafe extern "C" fn dc_do_heuristics_moves(
mut context: *mut dc_context_t,
mut folder: *const libc::c_char,
mut msg_id: uint32_t,
) {
// for already seen messages, folder may be different from msg->folder
let mut msg: *mut dc_msg_t = 0 as *mut dc_msg_t;
let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt;
if !(dc_sqlite3_get_config_int(
(*context).sql,
b"mvbox_move\x00" as *const u8 as *const libc::c_char,
1i32,
) == 0i32)
{
if !(0 == dc_is_inbox(context, folder) && 0 == dc_is_sentbox(context, folder)) {
msg = dc_msg_new_load(context, msg_id);
if !(0 != dc_msg_is_setupmessage(msg)) {
// do not move setup messages;
// there may be a non-delta device that wants to handle it
if 0 != dc_is_mvbox(context, folder) {
dc_update_msg_move_state(context, (*msg).rfc724_mid, DC_MOVE_STATE_STAY);
} else if 0 != (*msg).is_dc_message {
dc_job_add(
context,
200i32,
(*msg).id as libc::c_int,
0 as *const libc::c_char,
0i32,
);
dc_update_msg_move_state(context, (*msg).rfc724_mid, DC_MOVE_STATE_MOVING);
}
}
}
}
sqlite3_finalize(stmt);
dc_msg_unref(msg);
}

2585
src/dc_msg.rs Normal file

File diff suppressed because it is too large Load Diff

1491
src/dc_oauth2.rs Normal file

File diff suppressed because it is too large Load Diff

281
src/dc_openssl.rs Normal file
View File

@@ -0,0 +1,281 @@
use libc;
extern "C" {
#[no_mangle]
fn malloc(_: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn exit(_: libc::c_int) -> !;
/* return CRYPTO_NUM_LOCKS (shared libs!) */
#[no_mangle]
fn CRYPTO_num_locks() -> libc::c_int;
#[no_mangle]
fn CRYPTO_set_locking_callback(
func: Option<
unsafe extern "C" fn(
_: libc::c_int,
_: libc::c_int,
_: *const libc::c_char,
_: libc::c_int,
) -> (),
>,
);
#[no_mangle]
fn CRYPTO_set_id_callback(func: Option<unsafe extern "C" fn() -> libc::c_ulong>);
#[no_mangle]
fn CRYPTO_set_dynlock_create_callback(
dyn_create_function_0: Option<
unsafe extern "C" fn(
_: *const libc::c_char,
_: libc::c_int,
) -> *mut CRYPTO_dynlock_value,
>,
);
#[no_mangle]
fn CRYPTO_set_dynlock_lock_callback(
dyn_lock_function_0: Option<
unsafe extern "C" fn(
_: libc::c_int,
_: *mut CRYPTO_dynlock_value,
_: *const libc::c_char,
_: libc::c_int,
) -> (),
>,
);
#[no_mangle]
fn CRYPTO_set_dynlock_destroy_callback(
dyn_destroy_function_0: Option<
unsafe extern "C" fn(
_: *mut CRYPTO_dynlock_value,
_: *const libc::c_char,
_: libc::c_int,
) -> (),
>,
);
#[no_mangle]
fn OPENSSL_init();
#[no_mangle]
fn OPENSSL_add_all_algorithms_noconf();
#[no_mangle]
fn pthread_mutex_destroy(_: *mut pthread_mutex_t) -> libc::c_int;
#[no_mangle]
fn pthread_mutex_init(_: *mut pthread_mutex_t, _: *const pthread_mutexattr_t) -> libc::c_int;
#[no_mangle]
fn pthread_mutex_lock(_: *mut pthread_mutex_t) -> libc::c_int;
#[no_mangle]
fn pthread_mutex_unlock(_: *mut pthread_mutex_t) -> libc::c_int;
#[no_mangle]
fn pthread_self() -> pthread_t;
#[no_mangle]
fn mailstream_openssl_init_not_required();
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct __darwin_pthread_handler_rec {
pub __routine: Option<unsafe extern "C" fn(_: *mut libc::c_void) -> ()>,
pub __arg: *mut libc::c_void,
pub __next: *mut __darwin_pthread_handler_rec,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_mutex_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 56],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_mutexattr_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 8],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_t {
pub __sig: libc::c_long,
pub __cleanup_stack: *mut __darwin_pthread_handler_rec,
pub __opaque: [libc::c_char; 8176],
}
pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t;
pub type __darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t;
pub type __darwin_pthread_t = *mut _opaque_pthread_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct CRYPTO_dynlock_value {
pub mutex: pthread_mutex_t,
}
pub type pthread_mutex_t = __darwin_pthread_mutex_t;
pub type pthread_mutexattr_t = __darwin_pthread_mutexattr_t;
pub type pthread_t = __darwin_pthread_t;
#[no_mangle]
pub unsafe extern "C" fn dc_openssl_init_not_required() {
pthread_mutex_lock(&mut s_init_lock);
s_init_not_required = 1i32;
pthread_mutex_unlock(&mut s_init_lock);
}
static mut s_init_lock: pthread_mutex_t = _opaque_pthread_mutex_t {
__sig: 0x32aaaba7i32 as libc::c_long,
__opaque: [
0i32 as libc::c_char,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
};
static mut s_init_not_required: libc::c_int = 0i32;
static mut s_init_counter: libc::c_int = 0i32;
static mut s_mutex_buf: *mut pthread_mutex_t = 0 as *const pthread_mutex_t as *mut pthread_mutex_t;
unsafe extern "C" fn id_function() -> libc::c_ulong {
return pthread_self() as libc::c_ulong;
}
unsafe extern "C" fn locking_function(
mut mode: libc::c_int,
mut n: libc::c_int,
mut file: *const libc::c_char,
mut line: libc::c_int,
) {
if 0 != mode & 1i32 {
pthread_mutex_lock(&mut *s_mutex_buf.offset(n as isize));
} else {
pthread_mutex_unlock(&mut *s_mutex_buf.offset(n as isize));
};
}
unsafe extern "C" fn dyn_create_function(
mut file: *const libc::c_char,
mut line: libc::c_int,
) -> *mut CRYPTO_dynlock_value {
let mut value: *mut CRYPTO_dynlock_value =
malloc(::std::mem::size_of::<CRYPTO_dynlock_value>() as libc::c_ulong)
as *mut CRYPTO_dynlock_value;
if value.is_null() {
return 0 as *mut CRYPTO_dynlock_value;
}
pthread_mutex_init(&mut (*value).mutex, 0 as *const pthread_mutexattr_t);
return value;
}
unsafe extern "C" fn dyn_lock_function(
mut mode: libc::c_int,
mut l: *mut CRYPTO_dynlock_value,
mut file: *const libc::c_char,
mut line: libc::c_int,
) {
if 0 != mode & 1i32 {
pthread_mutex_lock(&mut (*l).mutex);
} else {
pthread_mutex_unlock(&mut (*l).mutex);
};
}
unsafe extern "C" fn dyn_destroy_function(
mut l: *mut CRYPTO_dynlock_value,
mut file: *const libc::c_char,
mut line: libc::c_int,
) {
pthread_mutex_destroy(&mut (*l).mutex);
free(l as *mut libc::c_void);
}
#[no_mangle]
pub unsafe extern "C" fn dc_openssl_init() {
pthread_mutex_lock(&mut s_init_lock);
s_init_counter += 1;
if s_init_counter == 1i32 {
if 0 == s_init_not_required {
s_mutex_buf = malloc(
(CRYPTO_num_locks() as libc::c_ulong)
.wrapping_mul(::std::mem::size_of::<pthread_mutex_t>() as libc::c_ulong),
) as *mut pthread_mutex_t;
if s_mutex_buf.is_null() {
exit(53i32);
}
let mut i: libc::c_int = 0i32;
while i < CRYPTO_num_locks() {
pthread_mutex_init(
&mut *s_mutex_buf.offset(i as isize),
0 as *const pthread_mutexattr_t,
);
i += 1
}
CRYPTO_set_id_callback(Some(id_function));
CRYPTO_set_locking_callback(Some(locking_function));
CRYPTO_set_dynlock_create_callback(Some(dyn_create_function));
CRYPTO_set_dynlock_lock_callback(Some(dyn_lock_function));
CRYPTO_set_dynlock_destroy_callback(Some(dyn_destroy_function));
OPENSSL_init();
OPENSSL_add_all_algorithms_noconf();
}
mailstream_openssl_init_not_required();
}
pthread_mutex_unlock(&mut s_init_lock);
}
#[no_mangle]
pub unsafe extern "C" fn dc_openssl_exit() {
pthread_mutex_lock(&mut s_init_lock);
if s_init_counter > 0i32 {
s_init_counter -= 1;
if s_init_counter == 0i32 && 0 == s_init_not_required {
CRYPTO_set_id_callback(None);
CRYPTO_set_locking_callback(None);
CRYPTO_set_dynlock_create_callback(None);
CRYPTO_set_dynlock_lock_callback(None);
CRYPTO_set_dynlock_destroy_callback(None);
let mut i: libc::c_int = 0i32;
while i < CRYPTO_num_locks() {
pthread_mutex_destroy(&mut *s_mutex_buf.offset(i as isize));
i += 1
}
free(s_mutex_buf as *mut libc::c_void);
s_mutex_buf = 0 as *mut pthread_mutex_t
}
}
pthread_mutex_unlock(&mut s_init_lock);
}

332
src/dc_param.rs Normal file
View File

@@ -0,0 +1,332 @@
use libc;
extern "C" {
#[no_mangle]
fn calloc(_: libc::c_ulong, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn atol(_: *const libc::c_char) -> libc::c_long;
#[no_mangle]
fn exit(_: libc::c_int) -> !;
#[no_mangle]
fn strchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char;
#[no_mangle]
fn strlen(_: *const libc::c_char) -> libc::c_ulong;
/* string tools */
#[no_mangle]
fn dc_strdup(_: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn dc_ltrim(_: *mut libc::c_char);
#[no_mangle]
fn dc_rtrim(_: *mut libc::c_char);
#[no_mangle]
fn dc_str_replace(
haystack: *mut *mut libc::c_char,
needle: *const libc::c_char,
replacement: *const libc::c_char,
) -> libc::c_int;
#[no_mangle]
fn dc_mprintf(format: *const libc::c_char, _: ...) -> *mut libc::c_char;
}
pub type int32_t = libc::c_int;
pub type dc_param_t = _dc_param;
/* *
* @class dc_param_t
*
* An object for handling key=value parameter lists; for the key, curently only
* a single character is allowed.
*
* The object is used eg. by dc_chat_t or dc_msg_t, for readable paramter names,
* these classes define some DC_PARAM_* constantats.
*
* Only for library-internal use.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_param {
pub packed: *mut libc::c_char,
}
/* for msgs and jobs */
/* for msgs */
/* for msgs */
/* for msgs */
/* for msgs */
/* for msgs: incoming: message is encryoted, outgoing: guarantee E2EE or the message is not send */
/* for msgs: decrypted with validation errors or without mutual set, if neither 'c' nor 'e' are preset, the messages is only transport encrypted */
/* for msgs: force unencrypted message, either DC_FP_ADD_AUTOCRYPT_HEADER (1), DC_FP_NO_AUTOCRYPT_HEADER (2) or 0 */
/* for msgs: an incoming message which requestes a MDN (aka read receipt) */
/* for msgs */
/* for msgs */
/* for msgs */
/* for msgs */
/* for msgs */
/* for msgs */
/* for msgs */
/* for msgs in PREPARING: space-separated list of message IDs of forwarded copies */
/* for jobs */
/* for jobs */
/* for jobs */
/* for jobs: space-separated list of message recipients */
/* for groups */
/* for groups and contacts */
/* for chats */
// values for DC_PARAM_FORCE_PLAINTEXT
/* user functions */
#[no_mangle]
pub unsafe extern "C" fn dc_param_exists(
mut param: *mut dc_param_t,
mut key: libc::c_int,
) -> libc::c_int {
let mut p2: *mut libc::c_char = 0 as *mut libc::c_char;
if param.is_null() || key == 0i32 {
return 0i32;
}
return if !find_param((*param).packed, key, &mut p2).is_null() {
1i32
} else {
0i32
};
}
unsafe extern "C" fn find_param(
mut haystack: *mut libc::c_char,
mut key: libc::c_int,
mut ret_p2: *mut *mut libc::c_char,
) -> *mut libc::c_char {
let mut p1: *mut libc::c_char = 0 as *mut libc::c_char;
let mut p2: *mut libc::c_char = 0 as *mut libc::c_char;
p1 = haystack;
loop {
if p1.is_null() || *p1 as libc::c_int == 0i32 {
return 0 as *mut libc::c_char;
} else {
if *p1 as libc::c_int == key && *p1.offset(1isize) as libc::c_int == '=' as i32 {
break;
}
p1 = strchr(p1, '\n' as i32);
if !p1.is_null() {
p1 = p1.offset(1isize)
}
}
}
p2 = strchr(p1, '\n' as i32);
if p2.is_null() {
p2 = &mut *p1.offset(strlen(p1) as isize) as *mut libc::c_char
}
*ret_p2 = p2;
return p1;
}
/* the value may be an empty string, "def" is returned only if the value unset. The result must be free()'d in any case. */
#[no_mangle]
pub unsafe extern "C" fn dc_param_get(
mut param: *const dc_param_t,
mut key: libc::c_int,
mut def: *const libc::c_char,
) -> *mut libc::c_char {
let mut p1: *mut libc::c_char = 0 as *mut libc::c_char;
let mut p2: *mut libc::c_char = 0 as *mut libc::c_char;
let mut bak: libc::c_char = 0i32 as libc::c_char;
let mut ret: *mut libc::c_char = 0 as *mut libc::c_char;
if param.is_null() || key == 0i32 {
return if !def.is_null() {
dc_strdup(def)
} else {
0 as *mut libc::c_char
};
}
p1 = find_param((*param).packed, key, &mut p2);
if p1.is_null() {
return if !def.is_null() {
dc_strdup(def)
} else {
0 as *mut libc::c_char
};
}
p1 = p1.offset(2isize);
bak = *p2;
*p2 = 0i32 as libc::c_char;
ret = dc_strdup(p1);
dc_rtrim(ret);
*p2 = bak;
return ret;
}
#[no_mangle]
pub unsafe extern "C" fn dc_param_get_int(
mut param: *const dc_param_t,
mut key: libc::c_int,
mut def: int32_t,
) -> int32_t {
if param.is_null() || key == 0i32 {
return def;
}
let mut str: *mut libc::c_char = dc_param_get(param, key, 0 as *const libc::c_char);
if str.is_null() {
return def;
}
let mut ret: int32_t = atol(str) as int32_t;
free(str as *mut libc::c_void);
return ret;
}
#[no_mangle]
pub unsafe extern "C" fn dc_param_set(
mut param: *mut dc_param_t,
mut key: libc::c_int,
mut value: *const libc::c_char,
) {
let mut old1: *mut libc::c_char = 0 as *mut libc::c_char;
let mut old2: *mut libc::c_char = 0 as *mut libc::c_char;
let mut new1: *mut libc::c_char = 0 as *mut libc::c_char;
if param.is_null() || key == 0i32 {
return;
}
old1 = (*param).packed;
old2 = 0 as *mut libc::c_char;
if !old1.is_null() {
let mut p1: *mut libc::c_char = 0 as *mut libc::c_char;
let mut p2: *mut libc::c_char = 0 as *mut libc::c_char;
p1 = find_param(old1, key, &mut p2);
if !p1.is_null() {
*p1 = 0i32 as libc::c_char;
old2 = p2
} else if value.is_null() {
return;
}
}
dc_rtrim(old1);
dc_ltrim(old2);
if !old1.is_null() && *old1.offset(0isize) as libc::c_int == 0i32 {
old1 = 0 as *mut libc::c_char
}
if !old2.is_null() && *old2.offset(0isize) as libc::c_int == 0i32 {
old2 = 0 as *mut libc::c_char
}
if !value.is_null() {
new1 = dc_mprintf(
b"%s%s%c=%s%s%s\x00" as *const u8 as *const libc::c_char,
if !old1.is_null() {
old1
} else {
b"\x00" as *const u8 as *const libc::c_char
},
if !old1.is_null() {
b"\n\x00" as *const u8 as *const libc::c_char
} else {
b"\x00" as *const u8 as *const libc::c_char
},
key,
value,
if !old2.is_null() {
b"\n\x00" as *const u8 as *const libc::c_char
} else {
b"\x00" as *const u8 as *const libc::c_char
},
if !old2.is_null() {
old2
} else {
b"\x00" as *const u8 as *const libc::c_char
},
)
} else {
new1 = dc_mprintf(
b"%s%s%s\x00" as *const u8 as *const libc::c_char,
if !old1.is_null() {
old1
} else {
b"\x00" as *const u8 as *const libc::c_char
},
if !old1.is_null() && !old2.is_null() {
b"\n\x00" as *const u8 as *const libc::c_char
} else {
b"\x00" as *const u8 as *const libc::c_char
},
if !old2.is_null() {
old2
} else {
b"\x00" as *const u8 as *const libc::c_char
},
)
}
free((*param).packed as *mut libc::c_void);
(*param).packed = new1;
}
#[no_mangle]
pub unsafe extern "C" fn dc_param_set_int(
mut param: *mut dc_param_t,
mut key: libc::c_int,
mut value: int32_t,
) {
if param.is_null() || key == 0i32 {
return;
}
let mut value_str: *mut libc::c_char = dc_mprintf(
b"%i\x00" as *const u8 as *const libc::c_char,
value as libc::c_int,
);
if value_str.is_null() {
return;
}
dc_param_set(param, key, value_str);
free(value_str as *mut libc::c_void);
}
/* library-private */
#[no_mangle]
pub unsafe extern "C" fn dc_param_new() -> *mut dc_param_t {
let mut param: *mut dc_param_t = 0 as *mut dc_param_t;
param = calloc(
1i32 as libc::c_ulong,
::std::mem::size_of::<dc_param_t>() as libc::c_ulong,
) as *mut dc_param_t;
if param.is_null() {
exit(28i32);
}
(*param).packed = calloc(1i32 as libc::c_ulong, 1i32 as libc::c_ulong) as *mut libc::c_char;
return param;
}
#[no_mangle]
pub unsafe extern "C" fn dc_param_empty(mut param: *mut dc_param_t) {
if param.is_null() {
return;
}
*(*param).packed.offset(0isize) = 0i32 as libc::c_char;
}
#[no_mangle]
pub unsafe extern "C" fn dc_param_unref(mut param: *mut dc_param_t) {
if param.is_null() {
return;
}
dc_param_empty(param);
free((*param).packed as *mut libc::c_void);
free(param as *mut libc::c_void);
}
#[no_mangle]
pub unsafe extern "C" fn dc_param_set_packed(
mut param: *mut dc_param_t,
mut packed: *const libc::c_char,
) {
if param.is_null() {
return;
}
dc_param_empty(param);
if !packed.is_null() {
free((*param).packed as *mut libc::c_void);
(*param).packed = dc_strdup(packed)
};
}
#[no_mangle]
pub unsafe extern "C" fn dc_param_set_urlencoded(
mut param: *mut dc_param_t,
mut urlencoded: *const libc::c_char,
) {
if param.is_null() {
return;
}
dc_param_empty(param);
if !urlencoded.is_null() {
free((*param).packed as *mut libc::c_void);
(*param).packed = dc_strdup(urlencoded);
dc_str_replace(
&mut (*param).packed,
b"&\x00" as *const u8 as *const libc::c_char,
b"\n\x00" as *const u8 as *const libc::c_char,
);
};
}

1687
src/dc_pgp.rs Normal file

File diff suppressed because it is too large Load Diff

1223
src/dc_qr.rs Normal file

File diff suppressed because it is too large Load Diff

4124
src/dc_receive_imf.rs Normal file

File diff suppressed because it is too large Load Diff

1245
src/dc_saxparser.rs Normal file

File diff suppressed because it is too large Load Diff

2572
src/dc_securejoin.rs Normal file

File diff suppressed because it is too large Load Diff

368
src/dc_simplify.rs Normal file
View File

@@ -0,0 +1,368 @@
use libc;
extern "C" {
#[no_mangle]
fn calloc(_: libc::c_ulong, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn exit(_: libc::c_int) -> !;
#[no_mangle]
fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
#[no_mangle]
fn strlen(_: *const libc::c_char) -> libc::c_ulong;
#[no_mangle]
fn strncmp(_: *const libc::c_char, _: *const libc::c_char, _: libc::c_ulong) -> libc::c_int;
#[no_mangle]
fn strndup(_: *const libc::c_char, _: libc::c_ulong) -> *mut libc::c_char;
/* string tools */
#[no_mangle]
fn dc_strdup(_: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn dc_remove_cr_chars(_: *mut libc::c_char);
#[no_mangle]
fn dc_split_into_lines(buf_terminated: *const libc::c_char) -> *mut carray;
#[no_mangle]
fn dc_free_splitted_lines(lines: *mut carray);
#[no_mangle]
fn dc_strbuilder_init(_: *mut dc_strbuilder_t, init_bytes: libc::c_int);
#[no_mangle]
fn dc_strbuilder_cat(_: *mut dc_strbuilder_t, text: *const libc::c_char) -> *mut libc::c_char;
/* ** library-internal *********************************************************/
#[no_mangle]
fn dc_dehtml(buf_terminated: *mut libc::c_char) -> *mut libc::c_char;
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct carray_s {
pub array: *mut *mut libc::c_void,
pub len: libc::c_uint,
pub max: libc::c_uint,
}
pub type carray = carray_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_strbuilder {
pub buf: *mut libc::c_char,
pub allocated: libc::c_int,
pub free: libc::c_int,
pub eos: *mut libc::c_char,
}
pub type dc_strbuilder_t = _dc_strbuilder;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_simplify {
pub is_forwarded: libc::c_int,
pub is_cut_at_begin: libc::c_int,
pub is_cut_at_end: libc::c_int,
}
/* ** library-private **********************************************************/
pub type dc_simplify_t = _dc_simplify;
#[inline]
unsafe extern "C" fn carray_count(mut array: *mut carray) -> libc::c_uint {
return (*array).len;
}
#[inline]
unsafe extern "C" fn carray_get(
mut array: *mut carray,
mut indx: libc::c_uint,
) -> *mut libc::c_void {
return *(*array).array.offset(indx as isize);
}
#[no_mangle]
pub unsafe extern "C" fn dc_simplify_new() -> *mut dc_simplify_t {
let mut simplify: *mut dc_simplify_t = 0 as *mut dc_simplify_t;
simplify = calloc(
1i32 as libc::c_ulong,
::std::mem::size_of::<dc_simplify_t>() as libc::c_ulong,
) as *mut dc_simplify_t;
if simplify.is_null() {
exit(31i32);
}
return simplify;
}
#[no_mangle]
pub unsafe extern "C" fn dc_simplify_unref(mut simplify: *mut dc_simplify_t) {
if simplify.is_null() {
return;
}
free(simplify as *mut libc::c_void);
}
/* Simplify and normalise text: Remove quotes, signatures, unnecessary
lineends etc.
The data returned from Simplify() must be free()'d when no longer used, private */
#[no_mangle]
pub unsafe extern "C" fn dc_simplify_simplify(
mut simplify: *mut dc_simplify_t,
mut in_unterminated: *const libc::c_char,
mut in_bytes: libc::c_int,
mut is_html: libc::c_int,
mut is_msgrmsg: libc::c_int,
) -> *mut libc::c_char {
/* create a copy of the given buffer */
let mut out: *mut libc::c_char = 0 as *mut libc::c_char;
let mut temp: *mut libc::c_char = 0 as *mut libc::c_char;
if simplify.is_null() || in_unterminated.is_null() || in_bytes <= 0i32 {
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
}
(*simplify).is_forwarded = 0i32;
(*simplify).is_cut_at_begin = 0i32;
(*simplify).is_cut_at_end = 0i32;
out = strndup(
in_unterminated as *mut libc::c_char,
in_bytes as libc::c_ulong,
);
if out.is_null() {
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
}
if 0 != is_html {
temp = dc_dehtml(out);
if !temp.is_null() {
free(out as *mut libc::c_void);
out = temp
}
}
dc_remove_cr_chars(out);
temp = dc_simplify_simplify_plain_text(simplify, out, is_msgrmsg);
if !temp.is_null() {
free(out as *mut libc::c_void);
out = temp
}
dc_remove_cr_chars(out);
return out;
}
/* ******************************************************************************
* Simplify Plain Text
******************************************************************************/
unsafe extern "C" fn dc_simplify_simplify_plain_text(
mut simplify: *mut dc_simplify_t,
mut buf_terminated: *const libc::c_char,
mut is_msgrmsg: libc::c_int,
) -> *mut libc::c_char {
/* This function ...
... removes all text after the line `-- ` (footer mark)
... removes full quotes at the beginning and at the end of the text -
these are all lines starting with the character `>`
... remove a non-empty line before the removed quote (contains sth. like "On 2.9.2016, Bjoern wrote:" in different formats and lanugages) */
/* split the given buffer into lines */
let mut lines: *mut carray = dc_split_into_lines(buf_terminated);
let mut l: libc::c_int = 0i32;
let mut l_first: libc::c_int = 0i32;
/* if l_last is -1, there are no lines */
let mut l_last: libc::c_int =
carray_count(lines).wrapping_sub(1i32 as libc::c_uint) as libc::c_int;
let mut line: *mut libc::c_char = 0 as *mut libc::c_char;
let mut footer_mark: libc::c_int = 0i32;
l = l_first;
while l <= l_last {
line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char;
if strcmp(line, b"-- \x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(line, b"-- \x00" as *const u8 as *const libc::c_char) == 0i32
{
footer_mark = 1i32
}
if strcmp(line, b"--\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(line, b"---\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(line, b"----\x00" as *const u8 as *const libc::c_char) == 0i32
{
footer_mark = 1i32;
(*simplify).is_cut_at_end = 1i32
}
if 0 != footer_mark {
l_last = l - 1i32;
/* done */
break;
} else {
l += 1
}
}
if l_last - l_first + 1i32 >= 3i32 {
let mut line0: *mut libc::c_char =
carray_get(lines, l_first as libc::c_uint) as *mut libc::c_char;
let mut line1: *mut libc::c_char =
carray_get(lines, (l_first + 1i32) as libc::c_uint) as *mut libc::c_char;
let mut line2: *mut libc::c_char =
carray_get(lines, (l_first + 2i32) as libc::c_uint) as *mut libc::c_char;
if strcmp(
line0,
b"---------- Forwarded message ----------\x00" as *const u8 as *const libc::c_char,
) == 0i32
&& strncmp(
line1,
b"From: \x00" as *const u8 as *const libc::c_char,
6i32 as libc::c_ulong,
) == 0i32
&& *line2.offset(0isize) as libc::c_int == 0i32
{
(*simplify).is_forwarded = 1i32;
l_first += 3i32
}
}
l = l_first;
while l <= l_last {
line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char;
if strncmp(
line,
b"-----\x00" as *const u8 as *const libc::c_char,
5i32 as libc::c_ulong,
) == 0i32
|| strncmp(
line,
b"_____\x00" as *const u8 as *const libc::c_char,
5i32 as libc::c_ulong,
) == 0i32
|| strncmp(
line,
b"=====\x00" as *const u8 as *const libc::c_char,
5i32 as libc::c_ulong,
) == 0i32
|| strncmp(
line,
b"*****\x00" as *const u8 as *const libc::c_char,
5i32 as libc::c_ulong,
) == 0i32
|| strncmp(
line,
b"~~~~~\x00" as *const u8 as *const libc::c_char,
5i32 as libc::c_ulong,
) == 0i32
{
l_last = l - 1i32;
(*simplify).is_cut_at_end = 1i32;
/* done */
break;
} else {
l += 1
}
}
if 0 == is_msgrmsg {
let mut l_lastQuotedLine: libc::c_int = -1i32;
l = l_last;
while l >= l_first {
line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char;
if 0 != is_plain_quote(line) {
l_lastQuotedLine = l
} else if 0 == is_empty_line(line) {
break;
}
l -= 1
}
if l_lastQuotedLine != -1i32 {
l_last = l_lastQuotedLine - 1i32;
(*simplify).is_cut_at_end = 1i32;
if l_last > 0i32 {
if 0 != is_empty_line(carray_get(lines, l_last as libc::c_uint) as *mut libc::c_char)
{
l_last -= 1
}
}
if l_last > 0i32 {
line = carray_get(lines, l_last as libc::c_uint) as *mut libc::c_char;
if 0 != is_quoted_headline(line) {
l_last -= 1
}
}
}
}
if 0 == is_msgrmsg {
let mut l_lastQuotedLine_0: libc::c_int = -1i32;
let mut hasQuotedHeadline: libc::c_int = 0i32;
l = l_first;
while l <= l_last {
line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char;
if 0 != is_plain_quote(line) {
l_lastQuotedLine_0 = l
} else if 0 == is_empty_line(line) {
if 0 != is_quoted_headline(line)
&& 0 == hasQuotedHeadline
&& l_lastQuotedLine_0 == -1i32
{
hasQuotedHeadline = 1i32
} else {
/* non-quoting line found */
break;
}
}
l += 1
}
if l_lastQuotedLine_0 != -1i32 {
l_first = l_lastQuotedLine_0 + 1i32;
(*simplify).is_cut_at_begin = 1i32
}
}
/* re-create buffer from the remaining lines */
let mut ret: dc_strbuilder_t = _dc_strbuilder {
buf: 0 as *mut libc::c_char,
allocated: 0,
free: 0,
eos: 0 as *mut libc::c_char,
};
dc_strbuilder_init(&mut ret, strlen(buf_terminated) as libc::c_int);
if 0 != (*simplify).is_cut_at_begin {
dc_strbuilder_cat(&mut ret, b"[...] \x00" as *const u8 as *const libc::c_char);
}
/* we write empty lines only in case and non-empty line follows */
let mut pending_linebreaks: libc::c_int = 0i32;
let mut content_lines_added: libc::c_int = 0i32;
l = l_first;
while l <= l_last {
line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char;
if 0 != is_empty_line(line) {
pending_linebreaks += 1
} else {
if 0 != content_lines_added {
if pending_linebreaks > 2i32 {
pending_linebreaks = 2i32
}
while 0 != pending_linebreaks {
dc_strbuilder_cat(&mut ret, b"\n\x00" as *const u8 as *const libc::c_char);
pending_linebreaks -= 1
}
}
dc_strbuilder_cat(&mut ret, line);
content_lines_added += 1;
pending_linebreaks = 1i32
}
l += 1
}
if 0 != (*simplify).is_cut_at_end
&& (0 == (*simplify).is_cut_at_begin || 0 != content_lines_added)
{
dc_strbuilder_cat(&mut ret, b" [...]\x00" as *const u8 as *const libc::c_char);
}
dc_free_splitted_lines(lines);
return ret.buf;
}
/* ******************************************************************************
* Tools
******************************************************************************/
unsafe extern "C" fn is_empty_line(mut buf: *const libc::c_char) -> libc::c_int {
/* force unsigned - otherwise the `> ' '` comparison will fail */
let mut p1: *const libc::c_uchar = buf as *const libc::c_uchar;
while 0 != *p1 {
if *p1 as libc::c_int > ' ' as i32 {
return 0i32;
}
p1 = p1.offset(1isize)
}
return 1i32;
}
unsafe extern "C" fn is_quoted_headline(mut buf: *const libc::c_char) -> libc::c_int {
/* This function may be called for the line _directly_ before a quote.
The function checks if the line contains sth. like "On 01.02.2016, xy@z wrote:" in various languages.
- Currently, we simply check if the last character is a ':'.
- Checking for the existance of an email address may fail (headlines may show the user's name instead of the address) */
let mut buf_len: libc::c_int = strlen(buf) as libc::c_int;
if buf_len > 80i32 {
return 0i32;
}
if buf_len > 0i32 && *buf.offset((buf_len - 1i32) as isize) as libc::c_int == ':' as i32 {
return 1i32;
}
return 0i32;
}
unsafe extern "C" fn is_plain_quote(mut buf: *const libc::c_char) -> libc::c_int {
if *buf.offset(0isize) as libc::c_int == '>' as i32 {
return 1i32;
}
return 0i32;
}

1435
src/dc_smtp.rs Normal file

File diff suppressed because it is too large Load Diff

2555
src/dc_sqlite3.rs Normal file

File diff suppressed because it is too large Load Diff

1109
src/dc_stock.rs Normal file

File diff suppressed because it is too large Load Diff

103
src/dc_strbuilder.rs Normal file
View File

@@ -0,0 +1,103 @@
use libc;
extern "C" {
#[no_mangle]
fn malloc(_: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn realloc(_: *mut libc::c_void, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn exit(_: libc::c_int) -> !;
#[no_mangle]
fn strcpy(_: *mut libc::c_char, _: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn strlen(_: *const libc::c_char) -> libc::c_ulong;
#[no_mangle]
fn vsnprintf(
_: *mut libc::c_char,
_: libc::c_ulong,
_: *const libc::c_char,
_: ::std::ffi::VaList,
) -> libc::c_int;
}
pub type __builtin_va_list = [__va_list_tag; 1];
#[derive(Copy, Clone)]
#[repr(C)]
pub struct __va_list_tag {
pub gp_offset: libc::c_uint,
pub fp_offset: libc::c_uint,
pub overflow_arg_area: *mut libc::c_void,
pub reg_save_area: *mut libc::c_void,
}
pub type __darwin_va_list = __builtin_va_list;
pub type va_list = __darwin_va_list;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_strbuilder {
pub buf: *mut libc::c_char,
pub allocated: libc::c_int,
pub free: libc::c_int,
pub eos: *mut libc::c_char,
}
pub type dc_strbuilder_t = _dc_strbuilder;
#[no_mangle]
pub unsafe extern "C" fn dc_strbuilder_init(
mut strbuilder: *mut dc_strbuilder_t,
mut init_bytes: libc::c_int,
) {
if strbuilder.is_null() {
return;
}
(*strbuilder).allocated = if init_bytes > 128i32 {
init_bytes
} else {
128i32
};
(*strbuilder).buf = malloc((*strbuilder).allocated as libc::c_ulong) as *mut libc::c_char;
if (*strbuilder).buf.is_null() {
exit(38i32);
}
*(*strbuilder).buf.offset(0isize) = 0i32 as libc::c_char;
(*strbuilder).free = (*strbuilder).allocated - 1i32;
(*strbuilder).eos = (*strbuilder).buf;
}
#[no_mangle]
pub unsafe extern "C" fn dc_strbuilder_cat(
mut strbuilder: *mut dc_strbuilder_t,
mut text: *const libc::c_char,
) -> *mut libc::c_char {
if strbuilder.is_null() || text.is_null() {
return 0 as *mut libc::c_char;
}
let mut len: libc::c_int = strlen(text) as libc::c_int;
if len > (*strbuilder).free {
let mut add_bytes: libc::c_int = if len > (*strbuilder).allocated {
len
} else {
(*strbuilder).allocated
};
let mut old_offset: libc::c_int = (*strbuilder).eos.wrapping_offset_from((*strbuilder).buf)
as libc::c_long as libc::c_int;
(*strbuilder).allocated = (*strbuilder).allocated + add_bytes;
(*strbuilder).buf = realloc(
(*strbuilder).buf as *mut libc::c_void,
((*strbuilder).allocated + add_bytes) as libc::c_ulong,
) as *mut libc::c_char;
if (*strbuilder).buf.is_null() {
exit(39i32);
}
(*strbuilder).free = (*strbuilder).free + add_bytes;
(*strbuilder).eos = (*strbuilder).buf.offset(old_offset as isize)
}
let mut ret: *mut libc::c_char = (*strbuilder).eos;
strcpy((*strbuilder).eos, text);
(*strbuilder).eos = (*strbuilder).eos.offset(len as isize);
(*strbuilder).free -= len;
return ret;
}
#[no_mangle]
pub unsafe extern "C" fn dc_strbuilder_empty(mut strbuilder: *mut dc_strbuilder_t) {
*(*strbuilder).buf.offset(0isize) = 0i32 as libc::c_char;
(*strbuilder).free = (*strbuilder).allocated - 1i32;
(*strbuilder).eos = (*strbuilder).buf;
}

908
src/dc_strencode.rs Normal file
View File

@@ -0,0 +1,908 @@
use libc;
use crate::dc_tools::*;
extern "C" {
#[no_mangle]
static mut _DefaultRuneLocale: _RuneLocale;
#[no_mangle]
fn __maskrune(_: __darwin_ct_rune_t, _: libc::c_ulong) -> libc::c_int;
#[no_mangle]
fn __tolower(_: __darwin_ct_rune_t) -> __darwin_ct_rune_t;
#[no_mangle]
fn mmap_string_new(init: *const libc::c_char) -> *mut MMAPString;
#[no_mangle]
fn mmap_string_free(string: *mut MMAPString);
#[no_mangle]
fn mmap_string_append(string: *mut MMAPString, val: *const libc::c_char) -> *mut MMAPString;
#[no_mangle]
fn mmap_string_append_len(
string: *mut MMAPString,
val: *const libc::c_char,
len: size_t,
) -> *mut MMAPString;
#[no_mangle]
fn mmap_string_append_c(string: *mut MMAPString, c: libc::c_char) -> *mut MMAPString;
#[no_mangle]
fn snprintf(
_: *mut libc::c_char,
_: libc::c_ulong,
_: *const libc::c_char,
_: ...
) -> libc::c_int;
#[no_mangle]
fn mailmime_encoded_phrase_parse(
default_fromcode: *const libc::c_char,
message: *const libc::c_char,
length: size_t,
indx: *mut size_t,
tocode: *const libc::c_char,
result: *mut *mut libc::c_char,
) -> libc::c_int;
#[no_mangle]
fn charconv(
tocode: *const libc::c_char,
fromcode: *const libc::c_char,
str: *const libc::c_char,
length: size_t,
result: *mut *mut libc::c_char,
) -> libc::c_int;
#[no_mangle]
fn malloc(_: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn free(_: *mut libc::c_void);
#[no_mangle]
fn exit(_: libc::c_int) -> !;
#[no_mangle]
fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn strchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char;
#[no_mangle]
fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
#[no_mangle]
fn strcpy(_: *mut libc::c_char, _: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn strlen(_: *const libc::c_char) -> libc::c_ulong;
#[no_mangle]
fn strdup(_: *const libc::c_char) -> *mut libc::c_char;
/* string tools */
#[no_mangle]
fn dc_strdup(_: *const libc::c_char) -> *mut libc::c_char;
#[no_mangle]
fn dc_null_terminate(_: *const libc::c_char, bytes: libc::c_int) -> *mut libc::c_char;
}
pub type __uint32_t = libc::c_uint;
pub type __darwin_ct_rune_t = libc::c_int;
pub type __darwin_size_t = libc::c_ulong;
pub type __darwin_wchar_t = libc::c_int;
pub type __darwin_rune_t = __darwin_wchar_t;
pub type size_t = __darwin_size_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _RuneEntry {
pub __min: __darwin_rune_t,
pub __max: __darwin_rune_t,
pub __map: __darwin_rune_t,
pub __types: *mut __uint32_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _RuneRange {
pub __nranges: libc::c_int,
pub __ranges: *mut _RuneEntry,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _RuneCharClass {
pub __name: [libc::c_char; 14],
pub __mask: __uint32_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _RuneLocale {
pub __magic: [libc::c_char; 8],
pub __encoding: [libc::c_char; 32],
pub __sgetrune: Option<
unsafe extern "C" fn(
_: *const libc::c_char,
_: __darwin_size_t,
_: *mut *const libc::c_char,
) -> __darwin_rune_t,
>,
pub __sputrune: Option<
unsafe extern "C" fn(
_: __darwin_rune_t,
_: *mut libc::c_char,
_: __darwin_size_t,
_: *mut *mut libc::c_char,
) -> libc::c_int,
>,
pub __invalid_rune: __darwin_rune_t,
pub __runetype: [__uint32_t; 256],
pub __maplower: [__darwin_rune_t; 256],
pub __mapupper: [__darwin_rune_t; 256],
pub __runetype_ext: _RuneRange,
pub __maplower_ext: _RuneRange,
pub __mapupper_ext: _RuneRange,
pub __variable: *mut libc::c_void,
pub __variable_len: libc::c_int,
pub __ncharclasses: libc::c_int,
pub __charclasses: *mut _RuneCharClass,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _MMAPString {
pub str_0: *mut libc::c_char,
pub len: size_t,
pub allocated_len: size_t,
pub fd: libc::c_int,
pub mmapped_size: size_t,
}
pub type MMAPString = _MMAPString;
pub type unnamed = libc::c_uint;
pub const MAILIMF_ERROR_FILE: unnamed = 4;
pub const MAILIMF_ERROR_INVAL: unnamed = 3;
pub const MAILIMF_ERROR_MEMORY: unnamed = 2;
pub const MAILIMF_ERROR_PARSE: unnamed = 1;
pub const MAILIMF_NO_ERROR: unnamed = 0;
pub type unnamed_0 = libc::c_uint;
pub const MAIL_CHARCONV_ERROR_CONV: unnamed_0 = 3;
pub const MAIL_CHARCONV_ERROR_MEMORY: unnamed_0 = 2;
pub const MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET: unnamed_0 = 1;
pub const MAIL_CHARCONV_NO_ERROR: unnamed_0 = 0;
#[inline]
unsafe extern "C" fn isascii(mut _c: libc::c_int) -> libc::c_int {
return (_c & !0x7fi32 == 0i32) as libc::c_int;
}
#[inline]
unsafe extern "C" fn __istype(mut _c: __darwin_ct_rune_t, mut _f: libc::c_ulong) -> libc::c_int {
return if 0 != isascii(_c) {
(0 != _DefaultRuneLocale.__runetype[_c as usize] as libc::c_ulong & _f) as libc::c_int
} else {
(0 != __maskrune(_c, _f)) as libc::c_int
};
}
#[inline]
unsafe extern "C" fn __isctype(
mut _c: __darwin_ct_rune_t,
mut _f: libc::c_ulong,
) -> __darwin_ct_rune_t {
return if _c < 0i32 || _c >= 1i32 << 8i32 {
0i32
} else {
(0 != _DefaultRuneLocale.__runetype[_c as usize] as libc::c_ulong & _f) as libc::c_int
};
}
#[no_mangle]
#[inline]
pub unsafe extern "C" fn isalnum(mut _c: libc::c_int) -> libc::c_int {
return __istype(_c, (0x100i64 | 0x400i64) as libc::c_ulong);
}
#[no_mangle]
#[inline]
pub unsafe extern "C" fn isdigit(mut _c: libc::c_int) -> libc::c_int {
return __isctype(_c, 0x400i64 as libc::c_ulong);
}
#[no_mangle]
pub unsafe extern "C" fn dc_urlencode(mut to_encode: *const libc::c_char) -> *mut libc::c_char {
let mut pstr: *const libc::c_char = to_encode;
if to_encode.is_null() {
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
}
let mut buf: *mut libc::c_char = malloc(
strlen(to_encode)
.wrapping_mul(3i32 as libc::c_ulong)
.wrapping_add(1i32 as libc::c_ulong),
) as *mut libc::c_char;
let mut pbuf: *mut libc::c_char = buf;
if buf.is_null() {
exit(46i32);
}
while 0 != *pstr {
if 0 != isalnum(*pstr as libc::c_int)
|| *pstr as libc::c_int == '-' as i32
|| *pstr as libc::c_int == '_' as i32
|| *pstr as libc::c_int == '.' as i32
|| *pstr as libc::c_int == '~' as i32
{
let fresh0 = pbuf;
pbuf = pbuf.offset(1);
*fresh0 = *pstr
} else if *pstr as libc::c_int == ' ' as i32 {
let fresh1 = pbuf;
pbuf = pbuf.offset(1);
*fresh1 = '+' as i32 as libc::c_char
} else {
let fresh2 = pbuf;
pbuf = pbuf.offset(1);
*fresh2 = '%' as i32 as libc::c_char;
let fresh3 = pbuf;
pbuf = pbuf.offset(1);
*fresh3 = int_2_uppercase_hex((*pstr as libc::c_int >> 4i32) as libc::c_char);
let fresh4 = pbuf;
pbuf = pbuf.offset(1);
*fresh4 = int_2_uppercase_hex((*pstr as libc::c_int & 15i32) as libc::c_char)
}
pstr = pstr.offset(1isize)
}
*pbuf = '\u{0}' as i32 as libc::c_char;
return buf;
}
/* ******************************************************************************
* URL encoding and decoding, RFC 3986
******************************************************************************/
unsafe extern "C" fn int_2_uppercase_hex(mut code: libc::c_char) -> libc::c_char {
static mut hex: [libc::c_char; 17] = [
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 0,
];
return hex[(code as libc::c_int & 15i32) as usize];
}
#[no_mangle]
pub unsafe extern "C" fn dc_urldecode(mut to_decode: *const libc::c_char) -> *mut libc::c_char {
let mut pstr: *const libc::c_char = to_decode;
if to_decode.is_null() {
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
}
let mut buf: *mut libc::c_char =
malloc(strlen(to_decode).wrapping_add(1i32 as libc::c_ulong)) as *mut libc::c_char;
let mut pbuf: *mut libc::c_char = buf;
if buf.is_null() {
exit(50i32);
}
while 0 != *pstr {
if *pstr as libc::c_int == '%' as i32 {
if 0 != *pstr.offset(1isize) as libc::c_int && 0 != *pstr.offset(2isize) as libc::c_int
{
let fresh5 = pbuf;
pbuf = pbuf.offset(1);
*fresh5 = ((hex_2_int(*pstr.offset(1isize)) as libc::c_int) << 4i32
| hex_2_int(*pstr.offset(2isize)) as libc::c_int)
as libc::c_char;
pstr = pstr.offset(2isize)
}
} else if *pstr as libc::c_int == '+' as i32 {
let fresh6 = pbuf;
pbuf = pbuf.offset(1);
*fresh6 = ' ' as i32 as libc::c_char
} else {
let fresh7 = pbuf;
pbuf = pbuf.offset(1);
*fresh7 = *pstr
}
pstr = pstr.offset(1isize)
}
*pbuf = '\u{0}' as i32 as libc::c_char;
return buf;
}
unsafe extern "C" fn hex_2_int(mut ch: libc::c_char) -> libc::c_char {
return (if 0 != isdigit(ch as libc::c_int) {
ch as libc::c_int - '0' as i32
} else {
tolower(ch as libc::c_int) - 'a' as i32 + 10i32
}) as libc::c_char;
}
#[no_mangle]
pub unsafe extern "C" fn dc_encode_header_words(
mut to_encode: *const libc::c_char,
) -> *mut libc::c_char {
let mut current_block: u64;
let mut ret_str: *mut libc::c_char = 0 as *mut libc::c_char;
let mut cur: *const libc::c_char = to_encode;
let mut mmapstr: *mut MMAPString = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
if to_encode.is_null() || mmapstr.is_null() {
current_block = 8550051112593613029;
} else {
current_block = 4644295000439058019;
}
loop {
match current_block {
8550051112593613029 => {
if !mmapstr.is_null() {
mmap_string_free(mmapstr);
}
break;
}
_ => {
if *cur as libc::c_int != '\u{0}' as i32 {
let mut begin: *const libc::c_char = 0 as *const libc::c_char;
let mut end: *const libc::c_char = 0 as *const libc::c_char;
let mut do_quote: libc::c_int = 0;
let mut quote_words: libc::c_int = 0;
begin = cur;
end = begin;
quote_words = 0i32;
do_quote = 1i32;
while *cur as libc::c_int != '\u{0}' as i32 {
get_word(cur, &mut cur, &mut do_quote);
if !(0 != do_quote) {
break;
}
quote_words = 1i32;
end = cur;
if *cur as libc::c_int != '\u{0}' as i32 {
cur = cur.offset(1isize)
}
}
if 0 != quote_words {
if 0 == quote_word(
b"utf-8\x00" as *const u8 as *const libc::c_char,
mmapstr,
begin,
end.wrapping_offset_from(begin) as libc::c_long as size_t,
) {
current_block = 8550051112593613029;
continue;
}
if *end as libc::c_int == ' ' as i32 || *end as libc::c_int == '\t' as i32 {
if mmap_string_append_c(mmapstr, *end).is_null() {
current_block = 8550051112593613029;
continue;
}
end = end.offset(1isize)
}
if *end as libc::c_int != '\u{0}' as i32 {
if mmap_string_append_len(
mmapstr,
end,
cur.wrapping_offset_from(end) as libc::c_long as size_t,
)
.is_null()
{
current_block = 8550051112593613029;
continue;
}
}
} else if mmap_string_append_len(
mmapstr,
begin,
cur.wrapping_offset_from(begin) as libc::c_long as size_t,
)
.is_null()
{
current_block = 8550051112593613029;
continue;
}
if !(*cur as libc::c_int == ' ' as i32 || *cur as libc::c_int == '\t' as i32) {
current_block = 4644295000439058019;
continue;
}
if mmap_string_append_c(mmapstr, *cur).is_null() {
current_block = 8550051112593613029;
continue;
}
cur = cur.offset(1isize);
current_block = 4644295000439058019;
} else {
ret_str = strdup((*mmapstr).str_0);
current_block = 8550051112593613029;
}
}
}
}
return ret_str;
}
unsafe extern "C" fn quote_word(
mut display_charset: *const libc::c_char,
mut mmapstr: *mut MMAPString,
mut word: *const libc::c_char,
mut size: size_t,
) -> libc::c_int {
let mut cur: *const libc::c_char = 0 as *const libc::c_char;
let mut i: size_t = 0i32 as size_t;
let mut hex: [libc::c_char; 4] = [0; 4];
let mut col: libc::c_int = 0i32;
if mmap_string_append(mmapstr, b"=?\x00" as *const u8 as *const libc::c_char).is_null() {
return 0i32;
}
if mmap_string_append(mmapstr, display_charset).is_null() {
return 0i32;
}
if mmap_string_append(mmapstr, b"?Q?\x00" as *const u8 as *const libc::c_char).is_null() {
return 0i32;
}
col = (*mmapstr).len as libc::c_int;
cur = word;
i = 0i32 as size_t;
while i < size {
let mut do_quote_char: libc::c_int = 0;
do_quote_char = 0i32;
match *cur as libc::c_int {
44 | 58 | 33 | 34 | 35 | 36 | 64 | 91 | 92 | 93 | 94 | 96 | 123 | 124 | 125 | 126
| 61 | 63 | 95 => do_quote_char = 1i32,
_ => {
if *cur as libc::c_uchar as libc::c_int >= 128i32 {
do_quote_char = 1i32
}
}
}
if 0 != do_quote_char {
snprintf(
hex.as_mut_ptr(),
4i32 as libc::c_ulong,
b"=%2.2X\x00" as *const u8 as *const libc::c_char,
*cur as libc::c_uchar as libc::c_int,
);
if mmap_string_append(mmapstr, hex.as_mut_ptr()).is_null() {
return 0i32;
}
col += 3i32
} else {
if *cur as libc::c_int == ' ' as i32 {
if mmap_string_append_c(mmapstr, '_' as i32 as libc::c_char).is_null() {
return 0i32;
}
} else if mmap_string_append_c(mmapstr, *cur).is_null() {
return 0i32;
}
col += 3i32
}
cur = cur.offset(1isize);
i = i.wrapping_add(1)
}
if mmap_string_append(mmapstr, b"?=\x00" as *const u8 as *const libc::c_char).is_null() {
return 0i32;
}
return 1i32;
}
unsafe extern "C" fn get_word(
mut begin: *const libc::c_char,
mut pend: *mut *const libc::c_char,
mut pto_be_quoted: *mut libc::c_int,
) {
let mut cur: *const libc::c_char = begin;
while *cur as libc::c_int != ' ' as i32
&& *cur as libc::c_int != '\t' as i32
&& *cur as libc::c_int != '\u{0}' as i32
{
cur = cur.offset(1isize)
}
*pto_be_quoted = to_be_quoted(
begin,
cur.wrapping_offset_from(begin) as libc::c_long as size_t,
);
*pend = cur;
}
/* ******************************************************************************
* Encode/decode header words, RFC 2047
******************************************************************************/
/* see comment below */
unsafe extern "C" fn to_be_quoted(mut word: *const libc::c_char, mut size: size_t) -> libc::c_int {
let mut cur: *const libc::c_char = word;
let mut i: size_t = 0i32 as size_t;
i = 0i32 as size_t;
while i < size {
match *cur as libc::c_int {
44 | 58 | 33 | 34 | 35 | 36 | 64 | 91 | 92 | 93 | 94 | 96 | 123 | 124 | 125 | 126
| 61 | 63 | 95 => return 1i32,
_ => {
if *cur as libc::c_uchar as libc::c_int >= 128i32 {
return 1i32;
}
}
}
cur = cur.offset(1isize);
i = i.wrapping_add(1)
}
return 0i32;
}
#[no_mangle]
pub unsafe extern "C" fn dc_decode_header_words(
mut in_0: *const libc::c_char,
) -> *mut libc::c_char {
if in_0.is_null() {
return 0 as *mut libc::c_char;
}
let mut out: *mut libc::c_char = 0 as *mut libc::c_char;
let mut cur_token: size_t = 0i32 as size_t;
let mut r: libc::c_int = mailmime_encoded_phrase_parse(
b"iso-8859-1\x00" as *const u8 as *const libc::c_char,
in_0,
strlen(in_0),
&mut cur_token,
b"utf-8\x00" as *const u8 as *const libc::c_char,
&mut out,
);
if r != MAILIMF_NO_ERROR as libc::c_int || out.is_null() {
out = dc_strdup(in_0)
}
return out;
}
#[no_mangle]
pub unsafe extern "C" fn dc_encode_modified_utf7(
mut to_encode: *const libc::c_char,
mut change_spaces: libc::c_int,
) -> *mut libc::c_char {
let mut utf8pos: libc::c_uint = 0i32 as libc::c_uint;
let mut utf8total: libc::c_uint = 0i32 as libc::c_uint;
let mut c: libc::c_uint = 0i32 as libc::c_uint;
let mut utf7mode: libc::c_uint = 0i32 as libc::c_uint;
let mut bitstogo: libc::c_uint = 0i32 as libc::c_uint;
let mut utf16flag: libc::c_uint = 0i32 as libc::c_uint;
let mut ucs4: libc::c_ulong = 0i32 as libc::c_ulong;
let mut bitbuf: libc::c_ulong = 0i32 as libc::c_ulong;
let mut dst: *mut libc::c_char = 0 as *mut libc::c_char;
let mut res: *mut libc::c_char = 0 as *mut libc::c_char;
if to_encode.is_null() {
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
}
res = malloc(
(2i32 as libc::c_ulong)
.wrapping_mul(strlen(to_encode))
.wrapping_add(1i32 as libc::c_ulong),
) as *mut libc::c_char;
dst = res;
if dst.is_null() {
exit(51i32);
}
utf7mode = 0i32 as libc::c_uint;
utf8total = 0i32 as libc::c_uint;
bitstogo = 0i32 as libc::c_uint;
utf8pos = 0i32 as libc::c_uint;
loop {
c = *to_encode as libc::c_uchar as libc::c_uint;
if !(c != '\u{0}' as i32 as libc::c_uint) {
break;
}
to_encode = to_encode.offset(1isize);
// normal character?
if c >= ' ' as i32 as libc::c_uint
&& c <= '~' as i32 as libc::c_uint
&& (c != '_' as i32 as libc::c_uint || 0 == change_spaces)
{
if 0 != utf7mode {
if 0 != bitstogo {
let fresh8 = dst;
dst = dst.offset(1);
*fresh8 = base64chars[(bitbuf << (6i32 as libc::c_uint).wrapping_sub(bitstogo)
& 0x3fi32 as libc::c_ulong)
as usize]
}
let fresh9 = dst;
dst = dst.offset(1);
*fresh9 = '-' as i32 as libc::c_char;
utf7mode = 0i32 as libc::c_uint;
utf8pos = 0i32 as libc::c_uint;
bitstogo = 0i32 as libc::c_uint;
utf8total = 0i32 as libc::c_uint
}
if 0 != change_spaces && c == ' ' as i32 as libc::c_uint {
let fresh10 = dst;
dst = dst.offset(1);
*fresh10 = '_' as i32 as libc::c_char
} else {
let fresh11 = dst;
dst = dst.offset(1);
*fresh11 = c as libc::c_char
}
if c == '&' as i32 as libc::c_uint {
let fresh12 = dst;
dst = dst.offset(1);
*fresh12 = '-' as i32 as libc::c_char
}
} else {
if 0 == utf7mode {
let fresh13 = dst;
dst = dst.offset(1);
*fresh13 = '&' as i32 as libc::c_char;
utf7mode = 1i32 as libc::c_uint
}
// encode ascii characters as themselves
if c < 0x80i32 as libc::c_uint {
ucs4 = c as libc::c_ulong
} else if 0 != utf8total {
ucs4 = ucs4 << 6i32 | c as libc::c_ulong & 0x3fu64;
utf8pos = utf8pos.wrapping_add(1);
if utf8pos < utf8total {
continue;
}
} else {
utf8pos = 1i32 as libc::c_uint;
if c < 0xe0i32 as libc::c_uint {
utf8total = 2i32 as libc::c_uint;
ucs4 = (c & 0x1fi32 as libc::c_uint) as libc::c_ulong
} else if c < 0xf0i32 as libc::c_uint {
utf8total = 3i32 as libc::c_uint;
ucs4 = (c & 0xfi32 as libc::c_uint) as libc::c_ulong
} else {
utf8total = 4i32 as libc::c_uint;
ucs4 = (c & 0x3i32 as libc::c_uint) as libc::c_ulong
}
continue;
}
utf8total = 0i32 as libc::c_uint;
loop {
if ucs4 >= 0x10000u64 {
ucs4 = ucs4.wrapping_sub(0x10000u64);
bitbuf = bitbuf << 16i32 | (ucs4 >> 10i32).wrapping_add(0xd800u64);
ucs4 = (ucs4 & 0x3ffu64).wrapping_add(0xdc00u64);
utf16flag = 1i32 as libc::c_uint
} else {
bitbuf = bitbuf << 16i32 | ucs4;
utf16flag = 0i32 as libc::c_uint
}
bitstogo = bitstogo.wrapping_add(16i32 as libc::c_uint);
while bitstogo >= 6i32 as libc::c_uint {
bitstogo = bitstogo.wrapping_sub(6i32 as libc::c_uint);
let fresh14 = dst;
dst = dst.offset(1);
*fresh14 = base64chars[(if 0 != bitstogo {
bitbuf >> bitstogo
} else {
bitbuf
} & 0x3fi32 as libc::c_ulong)
as usize]
}
if !(0 != utf16flag) {
break;
}
}
}
}
if 0 != utf7mode {
if 0 != bitstogo {
let fresh15 = dst;
dst = dst.offset(1);
*fresh15 = base64chars[(bitbuf << (6i32 as libc::c_uint).wrapping_sub(bitstogo)
& 0x3fi32 as libc::c_ulong) as usize]
}
let fresh16 = dst;
dst = dst.offset(1);
*fresh16 = '-' as i32 as libc::c_char
}
*dst = '\u{0}' as i32 as libc::c_char;
return res;
}
/* ******************************************************************************
* Encode/decode modified UTF-7 as needed for IMAP, see RFC 2192
******************************************************************************/
// UTF7 modified base64 alphabet
static mut base64chars: [libc::c_char; 65] = [
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 44, 0,
];
#[no_mangle]
pub unsafe extern "C" fn dc_decode_modified_utf7(
mut to_decode: *const libc::c_char,
mut change_spaces: libc::c_int,
) -> *mut libc::c_char {
let mut c: libc::c_uint = 0i32 as libc::c_uint;
let mut i: libc::c_uint = 0i32 as libc::c_uint;
let mut bitcount: libc::c_uint = 0i32 as libc::c_uint;
let mut ucs4: libc::c_ulong = 0i32 as libc::c_ulong;
let mut utf16: libc::c_ulong = 0i32 as libc::c_ulong;
let mut bitbuf: libc::c_ulong = 0i32 as libc::c_ulong;
let mut base64: [libc::c_uchar; 256] = [0; 256];
let mut src: *const libc::c_char = 0 as *const libc::c_char;
let mut dst: *mut libc::c_char = 0 as *mut libc::c_char;
let mut res: *mut libc::c_char = 0 as *mut libc::c_char;
if to_decode.is_null() {
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
}
res = malloc(
(4i32 as libc::c_ulong)
.wrapping_mul(strlen(to_decode))
.wrapping_add(1i32 as libc::c_ulong),
) as *mut libc::c_char;
dst = res;
src = to_decode;
if dst.is_null() {
exit(52i32);
}
memset(
base64.as_mut_ptr() as *mut libc::c_void,
64i32,
::std::mem::size_of::<[libc::c_uchar; 256]>() as libc::c_ulong,
);
i = 0i32 as libc::c_uint;
while (i as libc::c_ulong) < ::std::mem::size_of::<[libc::c_char; 65]>() as libc::c_ulong {
base64[base64chars[i as usize] as libc::c_uint as usize] = i as libc::c_uchar;
i = i.wrapping_add(1)
}
while *src as libc::c_int != '\u{0}' as i32 {
let fresh17 = src;
src = src.offset(1);
c = *fresh17 as libc::c_uint;
if c != '&' as i32 as libc::c_uint || *src as libc::c_int == '-' as i32 {
if 0 != change_spaces && c == '_' as i32 as libc::c_uint {
let fresh18 = dst;
dst = dst.offset(1);
*fresh18 = ' ' as i32 as libc::c_char
} else {
let fresh19 = dst;
dst = dst.offset(1);
*fresh19 = c as libc::c_char
}
if c == '&' as i32 as libc::c_uint {
src = src.offset(1isize)
}
} else {
bitbuf = 0i32 as libc::c_ulong;
bitcount = 0i32 as libc::c_uint;
ucs4 = 0i32 as libc::c_ulong;
loop {
c = base64[*src as libc::c_uchar as usize] as libc::c_uint;
if !(c != 64i32 as libc::c_uint) {
break;
}
src = src.offset(1isize);
bitbuf = bitbuf << 6i32 | c as libc::c_ulong;
bitcount = bitcount.wrapping_add(6i32 as libc::c_uint);
// enough bits for a UTF-16 character?
if !(bitcount >= 16i32 as libc::c_uint) {
continue;
}
bitcount = bitcount.wrapping_sub(16i32 as libc::c_uint);
utf16 = if 0 != bitcount {
bitbuf >> bitcount
} else {
bitbuf
} & 0xffffi32 as libc::c_ulong;
// convert UTF16 to UCS4
if utf16 >= 0xd800u64 && utf16 <= 0xdbffu64 {
ucs4 = utf16.wrapping_sub(0xd800u64) << 10i32
} else {
if utf16 >= 0xdc00u64 && utf16 <= 0xdfffu64 {
ucs4 = ucs4
.wrapping_add(utf16.wrapping_sub(0xdc00u64).wrapping_add(0x10000u64))
} else {
ucs4 = utf16
}
if ucs4 <= 0x7fu64 {
*dst.offset(0isize) = ucs4 as libc::c_char;
dst = dst.offset(1isize)
} else if ucs4 <= 0x7ffu64 {
*dst.offset(0isize) =
(0xc0i32 as libc::c_ulong | ucs4 >> 6i32) as libc::c_char;
*dst.offset(1isize) = (0x80i32 as libc::c_ulong
| ucs4 & 0x3fi32 as libc::c_ulong)
as libc::c_char;
dst = dst.offset(2isize)
} else if ucs4 <= 0xffffu64 {
*dst.offset(0isize) =
(0xe0i32 as libc::c_ulong | ucs4 >> 12i32) as libc::c_char;
*dst.offset(1isize) = (0x80i32 as libc::c_ulong
| ucs4 >> 6i32 & 0x3fi32 as libc::c_ulong)
as libc::c_char;
*dst.offset(2isize) = (0x80i32 as libc::c_ulong
| ucs4 & 0x3fi32 as libc::c_ulong)
as libc::c_char;
dst = dst.offset(3isize)
} else {
*dst.offset(0isize) =
(0xf0i32 as libc::c_ulong | ucs4 >> 18i32) as libc::c_char;
*dst.offset(1isize) = (0x80i32 as libc::c_ulong
| ucs4 >> 12i32 & 0x3fi32 as libc::c_ulong)
as libc::c_char;
*dst.offset(2isize) = (0x80i32 as libc::c_ulong
| ucs4 >> 6i32 & 0x3fi32 as libc::c_ulong)
as libc::c_char;
*dst.offset(3isize) = (0x80i32 as libc::c_ulong
| ucs4 & 0x3fi32 as libc::c_ulong)
as libc::c_char;
dst = dst.offset(4isize)
}
}
}
if *src as libc::c_int == '-' as i32 {
src = src.offset(1isize)
}
}
}
*dst = '\u{0}' as i32 as libc::c_char;
return res;
}
#[no_mangle]
pub unsafe extern "C" fn dc_needs_ext_header(mut to_check: *const libc::c_char) -> libc::c_int {
if !to_check.is_null() {
while 0 != *to_check {
if 0 == isalnum(*to_check as libc::c_int)
&& *to_check as libc::c_int != '-' as i32
&& *to_check as libc::c_int != '_' as i32
&& *to_check as libc::c_int != '.' as i32
&& *to_check as libc::c_int != '~' as i32
{
return 1i32;
}
to_check = to_check.offset(1isize)
}
}
return 0i32;
}
#[no_mangle]
pub unsafe extern "C" fn dc_encode_ext_header(
mut to_encode: *const libc::c_char,
) -> *mut libc::c_char {
let mut pstr: *const libc::c_char = to_encode;
if to_encode.is_null() {
return dc_strdup(b"utf-8\'\'\x00" as *const u8 as *const libc::c_char);
}
let mut buf: *mut libc::c_char = malloc(
strlen(b"utf-8\'\'\x00" as *const u8 as *const libc::c_char)
.wrapping_add(strlen(to_encode).wrapping_mul(3i32 as libc::c_ulong))
.wrapping_add(1i32 as libc::c_ulong),
) as *mut libc::c_char;
if buf.is_null() {
exit(46i32);
}
let mut pbuf: *mut libc::c_char = buf;
strcpy(pbuf, b"utf-8\'\'\x00" as *const u8 as *const libc::c_char);
pbuf = pbuf.offset(strlen(pbuf) as isize);
while 0 != *pstr {
if 0 != isalnum(*pstr as libc::c_int)
|| *pstr as libc::c_int == '-' as i32
|| *pstr as libc::c_int == '_' as i32
|| *pstr as libc::c_int == '.' as i32
|| *pstr as libc::c_int == '~' as i32
{
let fresh20 = pbuf;
pbuf = pbuf.offset(1);
*fresh20 = *pstr
} else {
let fresh21 = pbuf;
pbuf = pbuf.offset(1);
*fresh21 = '%' as i32 as libc::c_char;
let fresh22 = pbuf;
pbuf = pbuf.offset(1);
*fresh22 = int_2_uppercase_hex((*pstr as libc::c_int >> 4i32) as libc::c_char);
let fresh23 = pbuf;
pbuf = pbuf.offset(1);
*fresh23 = int_2_uppercase_hex((*pstr as libc::c_int & 15i32) as libc::c_char)
}
pstr = pstr.offset(1isize)
}
*pbuf = '\u{0}' as i32 as libc::c_char;
return buf;
}
#[no_mangle]
pub unsafe extern "C" fn dc_decode_ext_header(
mut to_decode: *const libc::c_char,
) -> *mut libc::c_char {
let mut decoded: *mut libc::c_char = 0 as *mut libc::c_char;
let mut charset: *mut libc::c_char = 0 as *mut libc::c_char;
let mut p2: *const libc::c_char = 0 as *const libc::c_char;
if !to_decode.is_null() {
// get char set
p2 = strchr(to_decode, '\'' as i32);
if !(p2.is_null() || p2 == to_decode) {
/*no empty charset allowed*/
charset = dc_null_terminate(
to_decode,
p2.wrapping_offset_from(to_decode) as libc::c_long as libc::c_int,
);
p2 = p2.offset(1isize);
// skip language
p2 = strchr(p2, '\'' as i32);
if !p2.is_null() {
p2 = p2.offset(1isize);
decoded = dc_urldecode(p2);
if !charset.is_null()
&& strcmp(charset, b"utf-8\x00" as *const u8 as *const libc::c_char) != 0i32
&& strcmp(charset, b"UTF-8\x00" as *const u8 as *const libc::c_char) != 0i32
{
let mut converted: *mut libc::c_char = 0 as *mut libc::c_char;
let mut r: libc::c_int = charconv(
b"utf-8\x00" as *const u8 as *const libc::c_char,
charset,
decoded,
strlen(decoded),
&mut converted,
);
if r == MAIL_CHARCONV_NO_ERROR as libc::c_int && !converted.is_null() {
free(decoded as *mut libc::c_void);
decoded = converted
} else {
free(converted as *mut libc::c_void);
}
}
}
}
}
free(charset as *mut libc::c_void);
return if !decoded.is_null() {
decoded
} else {
dc_strdup(to_decode)
};
}

835
src/dc_token.rs Normal file
View File

@@ -0,0 +1,835 @@
use c2rust_bitfields::BitfieldStruct;
use libc;
extern "C" {
pub type mailstream_cancel;
pub type sqlite3;
pub type sqlite3_stmt;
#[no_mangle]
fn time(_: *mut time_t) -> time_t;
#[no_mangle]
fn sqlite3_bind_int(_: *mut sqlite3_stmt, _: libc::c_int, _: libc::c_int) -> libc::c_int;
#[no_mangle]
fn sqlite3_bind_int64(_: *mut sqlite3_stmt, _: libc::c_int, _: sqlite3_int64) -> libc::c_int;
#[no_mangle]
fn sqlite3_bind_text(
_: *mut sqlite3_stmt,
_: libc::c_int,
_: *const libc::c_char,
_: libc::c_int,
_: Option<unsafe extern "C" fn(_: *mut libc::c_void) -> ()>,
) -> libc::c_int;
#[no_mangle]
fn sqlite3_step(_: *mut sqlite3_stmt) -> libc::c_int;
#[no_mangle]
fn sqlite3_column_text(_: *mut sqlite3_stmt, iCol: libc::c_int) -> *const libc::c_uchar;
#[no_mangle]
fn sqlite3_finalize(pStmt: *mut sqlite3_stmt) -> libc::c_int;
/* tools, these functions are compatible to the corresponding sqlite3_* functions */
#[no_mangle]
fn dc_sqlite3_prepare(_: *mut dc_sqlite3_t, sql: *const libc::c_char) -> *mut sqlite3_stmt;
#[no_mangle]
fn dc_strdup_keep_null(_: *const libc::c_char) -> *mut libc::c_char;
}
pub type __darwin_size_t = libc::c_ulong;
pub type __darwin_ssize_t = libc::c_long;
pub type __darwin_time_t = libc::c_long;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_cond_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 40],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _opaque_pthread_mutex_t {
pub __sig: libc::c_long,
pub __opaque: [libc::c_char; 56],
}
pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t;
pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t;
pub type uintptr_t = libc::c_ulong;
pub type size_t = __darwin_size_t;
pub type uint8_t = libc::c_uchar;
pub type uint32_t = libc::c_uint;
pub type ssize_t = __darwin_ssize_t;
pub type time_t = __darwin_time_t;
pub type pthread_cond_t = __darwin_pthread_cond_t;
pub type pthread_mutex_t = __darwin_pthread_mutex_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct carray_s {
pub array: *mut *mut libc::c_void,
pub len: libc::c_uint,
pub max: libc::c_uint,
}
pub type carray = carray_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream {
pub buffer_max_size: size_t,
pub write_buffer: *mut libc::c_char,
pub write_buffer_len: size_t,
pub read_buffer: *mut libc::c_char,
pub read_buffer_len: size_t,
pub low: *mut mailstream_low,
pub idle: *mut mailstream_cancel,
pub idling: libc::c_int,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
pub type mailstream = _mailstream;
pub type mailstream_low = _mailstream_low;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _mailstream_low {
pub data: *mut libc::c_void,
pub driver: *mut mailstream_low_driver,
pub privacy: libc::c_int,
pub identifier: *mut libc::c_char,
pub timeout: libc::c_ulong,
pub logger: Option<
unsafe extern "C" fn(
_: *mut mailstream_low,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailstream_low_driver {
pub mailstream_read: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *mut libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_write: Option<
unsafe extern "C" fn(_: *mut mailstream_low, _: *const libc::c_void, _: size_t) -> ssize_t,
>,
pub mailstream_close: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_get_fd: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_free: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_cancel: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> ()>,
pub mailstream_get_cancel:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut mailstream_cancel>,
pub mailstream_get_certificate_chain:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> *mut carray>,
pub mailstream_setup_idle: Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_unsetup_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
pub mailstream_interrupt_idle:
Option<unsafe extern "C" fn(_: *mut mailstream_low) -> libc::c_int>,
}
pub type progress_function = unsafe extern "C" fn(_: size_t, _: size_t) -> ();
pub type mailprogress_function =
unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _MMAPString {
pub str_0: *mut libc::c_char,
pub len: size_t,
pub allocated_len: size_t,
pub fd: libc::c_int,
pub mmapped_size: size_t,
}
pub type MMAPString = _MMAPString;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clistcell_s {
pub data: *mut libc::c_void,
pub previous: *mut clistcell_s,
pub next: *mut clistcell_s,
}
pub type clistcell = clistcell_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct clist_s {
pub first: *mut clistcell,
pub last: *mut clistcell,
pub count: libc::c_int,
}
pub type clist = clist_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailsmtp {
pub stream: *mut mailstream,
pub progr_rate: size_t,
pub progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub response: *mut libc::c_char,
pub line_buffer: *mut MMAPString,
pub response_buffer: *mut MMAPString,
pub esmtp: libc::c_int,
pub auth: libc::c_int,
pub smtp_sasl: unnamed,
pub smtp_max_msg_size: size_t,
pub smtp_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub smtp_progress_context: *mut libc::c_void,
pub response_code: libc::c_int,
pub smtp_timeout: time_t,
pub smtp_logger: Option<
unsafe extern "C" fn(
_: *mut mailsmtp,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub smtp_logger_context: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_capability_data {
pub cap_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att_body_section {
pub sec_section: *mut mailimap_section,
pub sec_origin_octet: uint32_t,
pub sec_body_part: *mut libc::c_char,
pub sec_length: size_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section {
pub sec_spec: *mut mailimap_section_spec,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_spec {
pub sec_type: libc::c_int,
pub sec_data: unnamed_0,
pub sec_text: *mut mailimap_section_text,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_text {
pub sec_type: libc::c_int,
pub sec_msgtext: *mut mailimap_section_msgtext,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_msgtext {
pub sec_type: libc::c_int,
pub sec_header_list: *mut mailimap_header_list,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_header_list {
pub hdr_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_0 {
pub sec_msgtext: *mut mailimap_section_msgtext,
pub sec_part: *mut mailimap_section_part,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_section_part {
pub sec_id: *mut clist,
}
pub type mailimap_msg_body_handler = unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_flag_list {
pub fl_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_mailbox_data_status {
pub st_mailbox: *mut libc::c_char,
pub st_info_list: *mut clist,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_msg_att {
pub att_list: *mut clist,
pub att_number: uint32_t,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_att {
pub att_type: libc::c_int,
pub att_section: *mut mailimap_section,
pub att_offset: uint32_t,
pub att_size: uint32_t,
pub att_extension: *mut libc::c_char,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_fetch_type {
pub ft_type: libc::c_int,
pub ft_data: unnamed_1,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union unnamed_1 {
pub ft_fetch_att: *mut mailimap_fetch_att,
pub ft_fetch_att_list: *mut clist,
}
pub type mailimap_msg_att_handler =
unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ();
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap {
pub imap_response: *mut libc::c_char,
pub imap_stream: *mut mailstream,
pub imap_progr_rate: size_t,
pub imap_progr_fun: Option<unsafe extern "C" fn(_: size_t, _: size_t) -> ()>,
pub imap_stream_buffer: *mut MMAPString,
pub imap_response_buffer: *mut MMAPString,
pub imap_state: libc::c_int,
pub imap_tag: libc::c_int,
pub imap_connection_info: *mut mailimap_connection_info,
pub imap_selection_info: *mut mailimap_selection_info,
pub imap_response_info: *mut mailimap_response_info,
pub imap_sasl: unnamed_2,
pub imap_idle_timestamp: time_t,
pub imap_idle_maxdelay: time_t,
pub imap_body_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_items_progress_fun:
Option<unsafe extern "C" fn(_: size_t, _: size_t, _: *mut libc::c_void) -> ()>,
pub imap_progress_context: *mut libc::c_void,
pub imap_msg_att_handler:
Option<unsafe extern "C" fn(_: *mut mailimap_msg_att, _: *mut libc::c_void) -> ()>,
pub imap_msg_att_handler_context: *mut libc::c_void,
pub imap_msg_body_handler: Option<
unsafe extern "C" fn(
_: libc::c_int,
_: *mut mailimap_msg_att_body_section,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> bool,
>,
pub imap_msg_body_handler_context: *mut libc::c_void,
pub imap_timeout: time_t,
pub imap_logger: Option<
unsafe extern "C" fn(
_: *mut mailimap,
_: libc::c_int,
_: *const libc::c_char,
_: size_t,
_: *mut libc::c_void,
) -> (),
>,
pub imap_logger_context: *mut libc::c_void,
pub is_163_workaround_enabled: libc::c_int,
pub is_rambler_workaround_enabled: libc::c_int,
pub is_qip_workaround_enabled: libc::c_int,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct unnamed_2 {
pub sasl_conn: *mut libc::c_void,
pub sasl_server_fqdn: *const libc::c_char,
pub sasl_login: *const libc::c_char,
pub sasl_auth_name: *const libc::c_char,
pub sasl_password: *const libc::c_char,
pub sasl_realm: *const libc::c_char,
pub sasl_secret: *mut libc::c_void,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_response_info {
pub rsp_alert: *mut libc::c_char,
pub rsp_parse: *mut libc::c_char,
pub rsp_badcharset: *mut clist,
pub rsp_trycreate: libc::c_int,
pub rsp_mailbox_list: *mut clist,
pub rsp_mailbox_lsub: *mut clist,
pub rsp_search_result: *mut clist,
pub rsp_status: *mut mailimap_mailbox_data_status,
pub rsp_expunged: *mut clist,
pub rsp_fetch_list: *mut clist,
pub rsp_extension_list: *mut clist,
pub rsp_atom: *mut libc::c_char,
pub rsp_value: *mut libc::c_char,
}
#[derive(BitfieldStruct, Clone, Copy)]
#[repr(C)]
pub struct mailimap_selection_info {
pub sel_perm_flags: *mut clist,
pub sel_perm: libc::c_int,
pub sel_uidnext: uint32_t,
pub sel_uidvalidity: uint32_t,
pub sel_first_unseen: uint32_t,
pub sel_flags: *mut mailimap_flag_list,
pub sel_exists: uint32_t,
pub sel_recent: uint32_t,
pub sel_unseen: uint32_t,
#[bitfield(name = "sel_has_exists", ty = "uint8_t", bits = "0..=0")]
#[bitfield(name = "sel_has_recent", ty = "uint8_t", bits = "1..=1")]
pub sel_has_exists_sel_has_recent: [u8; 1],
pub _pad: [u8; 3],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimap_connection_info {
pub imap_capability: *mut mailimap_capability_data,
}
/* define DC_USE_RPGP to enable use of rPGP instead of netpgp where available;
preferrably, this should be done in the project configuration currently */
//#define DC_USE_RPGP 1
/* Includes that are used frequently. This file may also be used to create predefined headers. */
/* * Structure behind dc_context_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_context {
pub magic: uint32_t,
pub userdata: *mut libc::c_void,
pub dbfile: *mut libc::c_char,
pub blobdir: *mut libc::c_char,
pub sql: *mut dc_sqlite3_t,
pub inbox: *mut dc_imap_t,
pub inboxidle_condmutex: pthread_mutex_t,
pub perform_inbox_jobs_needed: libc::c_int,
pub probe_imap_network: libc::c_int,
pub sentbox_thread: dc_jobthread_t,
pub mvbox_thread: dc_jobthread_t,
pub smtp: *mut dc_smtp_t,
pub smtpidle_cond: pthread_cond_t,
pub smtpidle_condmutex: pthread_mutex_t,
pub smtpidle_condflag: libc::c_int,
pub smtp_suspended: libc::c_int,
pub smtp_doing_jobs: libc::c_int,
pub perform_smtp_jobs_needed: libc::c_int,
pub probe_smtp_network: libc::c_int,
pub oauth2_critical: pthread_mutex_t,
pub cb: dc_callback_t,
pub os_name: *mut libc::c_char,
pub cmdline_sel_chat_id: uint32_t,
pub bob_expects: libc::c_int,
pub bobs_status: libc::c_int,
pub bobs_qr_scan: *mut dc_lot_t,
pub bobs_qr_critical: pthread_mutex_t,
pub last_smeared_timestamp: time_t,
pub smear_critical: pthread_mutex_t,
pub ongoing_running: libc::c_int,
pub shall_stop_ongoing: libc::c_int,
}
pub type dc_lot_t = _dc_lot;
/* * Structure behind dc_lot_t */
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_lot {
pub magic: uint32_t,
pub text1_meaning: libc::c_int,
pub text1: *mut libc::c_char,
pub text2: *mut libc::c_char,
pub timestamp: time_t,
pub state: libc::c_int,
pub id: uint32_t,
pub fingerprint: *mut libc::c_char,
pub invitenumber: *mut libc::c_char,
pub auth: *mut libc::c_char,
}
/* *
* Callback function that should be given to dc_context_new().
*
* @memberof dc_context_t
* @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 = Option<
unsafe extern "C" fn(
_: *mut dc_context_t,
_: libc::c_int,
_: uintptr_t,
_: uintptr_t,
) -> uintptr_t,
>;
/* *
* @mainpage Getting started
*
* This document describes how to handle the Delta Chat core library.
* For general information about Delta Chat itself,
* see <https://delta.chat> and <https://github.com/deltachat>.
*
* Let's start.
*
* First of all, you have to **define an event-handler-function**
* that is called by the library on specific events
* (eg. when the configuration is done or when fresh messages arrive).
* With this function you can create a Delta Chat context then:
*
* ~~~
* #include <deltachat.h>
*
* uintptr_t event_handler_func(dc_context_t* context, int event,
* uintptr_t data1, uintptr_t data2)
* {
* return 0; // for unhandled events, it is always safe to return 0
* }
*
* dc_context_t* context = dc_context_new(event_handler_func, NULL, NULL);
* ~~~
*
* After that, you should make sure,
* sending and receiving jobs are processed as needed.
* For this purpose, you have to **create two threads:**
*
* ~~~
* #include <pthread.h>
*
* void* imap_thread_func(void* context)
* {
* while (true) {
* dc_perform_imap_jobs(context);
* dc_perform_imap_fetch(context);
* dc_perform_imap_idle(context);
* }
* }
*
* void* smtp_thread_func(void* context)
* {
* while (true) {
* dc_perform_smtp_jobs(context);
* dc_perform_smtp_idle(context);
* }
* }
*
* static pthread_t imap_thread, smtp_thread;
* pthread_create(&imap_thread, NULL, imap_thread_func, context);
* pthread_create(&smtp_thread, NULL, smtp_thread_func, context);
* ~~~
*
* The example above uses "pthreads",
* however, you can also use anything else for thread handling.
* NB: The deltachat-core library itself does not create any threads on its own,
* however, functions, unless stated otherwise, are thread-safe.
*
* After that you can **define and open a database.**
* The database is a normal sqlite-file and is created as needed:
*
* ~~~
* dc_open(context, "example.db", NULL);
* ~~~
*
* Now you can **configure the context:**
*
* ~~~
* // use some real test credentials here
* dc_set_config(context, "addr", "alice@example.org");
* dc_set_config(context, "mail_pw", "***");
* dc_configure(context);
* ~~~
*
* dc_configure() returns immediately, the configuration itself may take a while
* and is done by a job in the imap-thread you've defined above.
* Once done, the #DC_EVENT_CONFIGURE_PROGRESS reports success
* to the event_handler_func() that is also defined above.
*
* The configuration result is saved in the database,
* on subsequent starts it is not needed to call dc_configure()
* (you can check this using dc_is_configured()).
*
* Now you can **send the first message:**
*
* ~~~
* // use a real testing address here
* uint32_t contact_id = dc_create_contact(context, NULL, "bob@example.org");
* uint32_t chat_id = dc_create_chat_by_contact_id(context, contact_id);
*
* dc_send_text_msg(context, chat_id, "Hi, here is my first message!");
* ~~~
*
* dc_send_text_msg() returns immediately;
* the sending itself is done by a job in the smtp-thread you've defined above.
* If you check the testing address (bob)
* and you should have received a normal email.
* Answer this email in any email program with "Got it!"
* and the imap-thread you've create above will **receive the message**.
*
* You can then **list all messages** of a chat as follow:
*
* ~~~
* dc_array_t* msglist = dc_get_chat_msgs(context, chat_id, 0, 0);
* for (int i = 0; i < dc_array_get_cnt(msglist); i++)
* {
* uint32_t msg_id = dc_array_get_id(msglist, i);
* dc_msg_t* msg = dc_get_msg(context, msg_id);
* char* text = dc_msg_get_text(msg);
*
* printf("Message %i: %s\n", i+1, text);
*
* free(text);
* dc_msg_unref(msg);
* }
* dc_array_unref(msglist);
* ~~~
*
* This will output the following two lines:
*
* ~~~
* Message 1: Hi, here is my first message!
* Message 2: Got it!
* ~~~
*
*
* ## Class reference
*
* For a class reference, see the "Classes" link atop.
*
*
* ## Further hints
*
* Here are some additional, unsorted hints that may be useful.
*
* - For `get`-functions, you have to unref the return value in some way.
*
* - Strings in function arguments or return values are usually UTF-8 encoded.
*
* - The issue-tracker for the core library is here:
* <https://github.com/deltachat/deltachat-core/issues>
*
* The following points are important mainly
* for the authors of the library itself:
*
* - For indentation, use tabs.
* Alignments that are not placed at the beginning of a line
* should be done with spaces.
*
* - For padding between functions,
* classes etc. use 2 empty lines
*
* - Source files are encoded as UTF-8 with Unix line endings
* (a simple `LF`, `0x0A` or `\n`)
*
* If you need further assistance,
* please do not hesitate to contact us
* through the channels shown at https://delta.chat/en/contribute
*
* Please keep in mind, that your derived work
* must respect the Mozilla Public License 2.0 of libdeltachat
* and the respective licenses of the libraries libdeltachat links with.
*
* See you.
*/
/* *
* @class dc_context_t
*
* An object representing a single account.
*
* Each account is linked to an IMAP/SMTP account and uses a separate
* SQLite database for offline functionality and for account-related
* settings.
*/
pub type dc_context_t = _dc_context;
/* ** library-private **********************************************************/
pub type dc_smtp_t = _dc_smtp;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_smtp {
pub etpan: *mut mailsmtp,
pub from: *mut libc::c_char,
pub esmtp: libc::c_int,
pub log_connect_errors: libc::c_int,
pub context: *mut dc_context_t,
pub error: *mut libc::c_char,
pub error_etpan: libc::c_int,
}
pub type dc_jobthread_t = _dc_jobthread;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_jobthread {
pub context: *mut dc_context_t,
pub name: *mut libc::c_char,
pub folder_config_name: *mut libc::c_char,
pub imap: *mut _dc_imap,
pub mutex: pthread_mutex_t,
pub idle_cond: pthread_cond_t,
pub idle_condflag: libc::c_int,
pub jobs_needed: libc::c_int,
pub suspended: libc::c_int,
pub using_handle: libc::c_int,
}
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_imap {
pub addr: *mut libc::c_char,
pub imap_server: *mut libc::c_char,
pub imap_port: libc::c_int,
pub imap_user: *mut libc::c_char,
pub imap_pw: *mut libc::c_char,
pub server_flags: libc::c_int,
pub connected: libc::c_int,
pub etpan: *mut mailimap,
pub idle_set_up: libc::c_int,
pub selected_folder: *mut libc::c_char,
pub selected_folder_needs_expunge: libc::c_int,
pub should_reconnect: libc::c_int,
pub can_idle: libc::c_int,
pub has_xlist: libc::c_int,
pub imap_delimiter: libc::c_char,
pub watch_folder: *mut libc::c_char,
pub watch_cond: pthread_cond_t,
pub watch_condmutex: pthread_mutex_t,
pub watch_condflag: libc::c_int,
pub fetch_type_prefetch: *mut mailimap_fetch_type,
pub fetch_type_body: *mut mailimap_fetch_type,
pub fetch_type_flags: *mut mailimap_fetch_type,
pub get_config: dc_get_config_t,
pub set_config: dc_set_config_t,
pub precheck_imf: dc_precheck_imf_t,
pub receive_imf: dc_receive_imf_t,
pub userData: *mut libc::c_void,
pub context: *mut dc_context_t,
pub log_connect_errors: libc::c_int,
pub skip_log_capabilities: libc::c_int,
}
pub type dc_receive_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: size_t,
_: *const libc::c_char,
_: uint32_t,
_: uint32_t,
) -> (),
>;
/* Purpose: Reading from IMAP servers with no dependencies to the database.
dc_context_t is only used for logging and to get information about
the online state. */
pub type dc_imap_t = _dc_imap;
pub type dc_precheck_imf_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
_: uint32_t,
) -> libc::c_int,
>;
pub type dc_set_config_t = Option<
unsafe extern "C" fn(_: *mut dc_imap_t, _: *const libc::c_char, _: *const libc::c_char) -> (),
>;
pub type dc_get_config_t = Option<
unsafe extern "C" fn(
_: *mut dc_imap_t,
_: *const libc::c_char,
_: *const libc::c_char,
) -> *mut libc::c_char,
>;
/* ** library-private **********************************************************/
pub type dc_sqlite3_t = _dc_sqlite3;
/* *
* Library-internal.
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _dc_sqlite3 {
pub cobj: *mut sqlite3,
pub context: *mut dc_context_t,
}
pub type sqlite_int64 = libc::c_longlong;
pub type sqlite3_int64 = sqlite_int64;
pub type sqlite3_destructor_type = Option<unsafe extern "C" fn(_: *mut libc::c_void) -> ()>;
// Token namespaces
pub type dc_tokennamespc_t = libc::c_uint;
pub const DC_TOKEN_AUTH: dc_tokennamespc_t = 110;
pub const DC_TOKEN_INVITENUMBER: dc_tokennamespc_t = 100;
// Functions to read/write token from/to the database. A token is any string associated with a key.
#[no_mangle]
pub unsafe extern "C" fn dc_token_save(
mut context: *mut dc_context_t,
mut namespc: dc_tokennamespc_t,
mut foreign_id: uint32_t,
mut token: *const libc::c_char,
) {
let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt;
if !(context.is_null() || (*context).magic != 0x11a11807i32 as libc::c_uint || token.is_null())
{
// foreign_id may be 0
stmt = dc_sqlite3_prepare(
(*context).sql,
b"INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);\x00"
as *const u8 as *const libc::c_char,
);
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_step(stmt);
}
sqlite3_finalize(stmt);
}
#[no_mangle]
pub unsafe extern "C" fn dc_token_lookup(
mut context: *mut dc_context_t,
mut namespc: dc_tokennamespc_t,
mut foreign_id: uint32_t,
) -> *mut libc::c_char {
let mut token: *mut libc::c_char = 0 as *mut libc::c_char;
let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt;
if !(context.is_null() || (*context).magic != 0x11a11807i32 as libc::c_uint) {
stmt = dc_sqlite3_prepare(
(*context).sql,
b"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;\x00" as *const u8
as *const libc::c_char,
);
sqlite3_bind_int(stmt, 1i32, namespc as libc::c_int);
sqlite3_bind_int(stmt, 2i32, foreign_id as libc::c_int);
sqlite3_step(stmt);
token = dc_strdup_keep_null(sqlite3_column_text(stmt, 0i32) as *mut libc::c_char)
}
sqlite3_finalize(stmt);
return token;
}
#[no_mangle]
pub unsafe extern "C" fn dc_token_exists(
mut context: *mut dc_context_t,
mut namespc: dc_tokennamespc_t,
mut token: *const libc::c_char,
) -> libc::c_int {
let mut exists: libc::c_int = 0i32;
let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt;
if !(context.is_null() || (*context).magic != 0x11a11807i32 as libc::c_uint || token.is_null())
{
stmt = dc_sqlite3_prepare(
(*context).sql,
b"SELECT id FROM tokens WHERE namespc=? AND token=?;\x00" as *const u8
as *const libc::c_char,
);
sqlite3_bind_int(stmt, 1i32, namespc as libc::c_int);
sqlite3_bind_text(stmt, 2i32, token, -1i32, None);
exists = (sqlite3_step(stmt) != 0i32) as libc::c_int
}
sqlite3_finalize(stmt);
return exists;
}

3109
src/dc_tools.rs Normal file

File diff suppressed because it is too large Load Diff

128
src/lib.rs Normal file
View File

@@ -0,0 +1,128 @@
#![allow(
dead_code,
mutable_transmutes,
non_camel_case_types,
non_snake_case,
non_upper_case_globals,
unused_assignments,
unused_mut
)]
#![feature(
c_variadic,
const_raw_ptr_to_usize_cast,
extern_types,
ptr_wrapping_offset_from
)]
#![allow(unused_attributes)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
pub mod dc_aheader;
pub mod dc_apeerstate;
pub mod dc_array;
pub mod dc_chat;
pub mod dc_chatlist;
pub mod dc_configure;
pub mod dc_contact;
pub mod dc_context;
pub mod dc_dehtml;
pub mod dc_e2ee;
pub mod dc_hash;
pub mod dc_imap;
pub mod dc_imex;
pub mod dc_job;
pub mod dc_jobthread;
pub mod dc_jsmn;
pub mod dc_key;
pub mod dc_keyhistory;
pub mod dc_keyring;
pub mod dc_location;
pub mod dc_log;
pub mod dc_loginparam;
pub mod dc_lot;
pub mod dc_mimefactory;
pub mod dc_mimeparser;
pub mod dc_move;
pub mod dc_msg;
pub mod dc_oauth2;
pub mod dc_openssl;
pub mod dc_param;
pub mod dc_pgp;
pub mod dc_qr;
pub mod dc_receive_imf;
pub mod dc_saxparser;
pub mod dc_securejoin;
pub mod dc_simplify;
pub mod dc_smtp;
pub mod dc_sqlite3;
pub mod dc_stock;
pub mod dc_strbuilder;
pub mod dc_strencode;
pub mod dc_token;
pub mod dc_tools;
#[cfg(test)]
mod tests {
use super::*;
use std::ffi::{CStr, CString};
use std::os::raw::c_int;
use std::ptr::NonNull;
use crate::dc_configure::dc_configure;
use crate::dc_context::*;
use crate::dc_job::{dc_perform_imap_fetch, dc_perform_imap_idle, dc_perform_imap_jobs};
extern "C" fn cb(ctx: *mut dc_context_t, event: c_int, data1: u64, data2: u64) -> u64 {
let info = if data2 > 0 {
Some(unsafe { CStr::from_ptr(data2 as *const _) })
} else {
None
};
println!("event: {} - {} - {:?}", event, data1, info);
0
}
struct Wrapper(NonNull<dc_context_t>);
unsafe impl std::marker::Send for Wrapper {}
unsafe impl std::marker::Sync for Wrapper {}
#[test]
fn test_basics() {
unsafe {
let mut ctx = dc_context_new(Some(cb), std::ptr::null_mut(), std::ptr::null_mut());
let info = dc_get_info(ctx);
let info_s = CStr::from_ptr(info);
println!("info: {:?}", info_s);
let dbfile = CString::new("hello.db").unwrap();
let blobdir = CString::new("hello").unwrap();
dc_open(ctx, dbfile.as_ptr(), blobdir.as_ptr());
let sendable_ctx = Wrapper(NonNull::new(ctx).unwrap());
dc_set_config(
ctx,
CString::new("addr").unwrap().as_ptr(),
CString::new("d@testrun.org").unwrap().as_ptr(),
);
dc_set_config(
ctx,
CString::new("mail_pw").unwrap().as_ptr(),
CString::new("__").unwrap().as_ptr(),
);
dc_configure(ctx);
std::thread::spawn(move || loop {
dc_perform_imap_jobs(sendable_ctx.0.as_ptr());
dc_perform_imap_fetch(sendable_ctx.0.as_ptr());
dc_perform_imap_idle(sendable_ctx.0.as_ptr());
})
.join();
}
}
}