mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
inital commit
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
*.db
|
||||
14
Cargo.toml
Normal file
14
Cargo.toml
Normal 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"
|
||||
28
build.rs
Normal file
28
build.rs
Normal 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
163
misc.c
Normal 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
23
misc.h
Normal 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
524
src/dc_aheader.rs
Normal 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
1428
src/dc_apeerstate.rs
Normal file
File diff suppressed because it is too large
Load Diff
1241
src/dc_array.rs
Normal file
1241
src/dc_array.rs
Normal file
File diff suppressed because it is too large
Load Diff
3697
src/dc_chat.rs
Normal file
3697
src/dc_chat.rs
Normal file
File diff suppressed because it is too large
Load Diff
1358
src/dc_chatlist.rs
Normal file
1358
src/dc_chatlist.rs
Normal file
File diff suppressed because it is too large
Load Diff
3154
src/dc_configure.rs
Normal file
3154
src/dc_configure.rs
Normal file
File diff suppressed because it is too large
Load Diff
2241
src/dc_contact.rs
Normal file
2241
src/dc_contact.rs
Normal file
File diff suppressed because it is too large
Load Diff
1958
src/dc_context.rs
Normal file
1958
src/dc_context.rs
Normal file
File diff suppressed because it is too large
Load Diff
269
src/dc_dehtml.rs
Normal file
269
src/dc_dehtml.rs
Normal 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
2908
src/dc_e2ee.rs
Normal file
File diff suppressed because it is too large
Load Diff
916
src/dc_hash.rs
Normal file
916
src/dc_hash.rs
Normal 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
3290
src/dc_imap.rs
Normal file
File diff suppressed because it is too large
Load Diff
2816
src/dc_imex.rs
Normal file
2816
src/dc_imex.rs
Normal file
File diff suppressed because it is too large
Load Diff
2652
src/dc_job.rs
Normal file
2652
src/dc_job.rs
Normal file
File diff suppressed because it is too large
Load Diff
1050
src/dc_jobthread.rs
Normal file
1050
src/dc_jobthread.rs
Normal file
File diff suppressed because it is too large
Load Diff
398
src/dc_jsmn.rs
Normal file
398
src/dc_jsmn.rs
Normal 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
1465
src/dc_key.rs
Normal file
File diff suppressed because it is too large
Load Diff
744
src/dc_keyhistory.rs
Normal file
744
src/dc_keyhistory.rs
Normal 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
866
src/dc_keyring.rs
Normal 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
1884
src/dc_location.rs
Normal file
File diff suppressed because it is too large
Load Diff
852
src/dc_log.rs
Normal file
852
src/dc_log.rs
Normal 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
1153
src/dc_loginparam.rs
Normal file
File diff suppressed because it is too large
Load Diff
986
src/dc_lot.rs
Normal file
986
src/dc_lot.rs
Normal 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
2920
src/dc_mimefactory.rs
Normal file
File diff suppressed because it is too large
Load Diff
3428
src/dc_mimeparser.rs
Normal file
3428
src/dc_mimeparser.rs
Normal file
File diff suppressed because it is too large
Load Diff
858
src/dc_move.rs
Normal file
858
src/dc_move.rs
Normal 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
2585
src/dc_msg.rs
Normal file
File diff suppressed because it is too large
Load Diff
1491
src/dc_oauth2.rs
Normal file
1491
src/dc_oauth2.rs
Normal file
File diff suppressed because it is too large
Load Diff
281
src/dc_openssl.rs
Normal file
281
src/dc_openssl.rs
Normal 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
332
src/dc_param.rs
Normal 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
1687
src/dc_pgp.rs
Normal file
File diff suppressed because it is too large
Load Diff
1223
src/dc_qr.rs
Normal file
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
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
1245
src/dc_saxparser.rs
Normal file
File diff suppressed because it is too large
Load Diff
2572
src/dc_securejoin.rs
Normal file
2572
src/dc_securejoin.rs
Normal file
File diff suppressed because it is too large
Load Diff
368
src/dc_simplify.rs
Normal file
368
src/dc_simplify.rs
Normal 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
1435
src/dc_smtp.rs
Normal file
File diff suppressed because it is too large
Load Diff
2555
src/dc_sqlite3.rs
Normal file
2555
src/dc_sqlite3.rs
Normal file
File diff suppressed because it is too large
Load Diff
1109
src/dc_stock.rs
Normal file
1109
src/dc_stock.rs
Normal file
File diff suppressed because it is too large
Load Diff
103
src/dc_strbuilder.rs
Normal file
103
src/dc_strbuilder.rs
Normal 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
908
src/dc_strencode.rs
Normal 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
835
src/dc_token.rs
Normal 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
3109
src/dc_tools.rs
Normal file
File diff suppressed because it is too large
Load Diff
128
src/lib.rs
Normal file
128
src/lib.rs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user