mirror of
https://github.com/chatmail/core.git
synced 2026-04-24 17:06:28 +03:00
refactor: remove x module and delete deadcode
This commit is contained in:
committed by
holger krekel
parent
b85f59798c
commit
05f9f454c3
@@ -24,7 +24,9 @@ use num_traits::{FromPrimitive, ToPrimitive};
|
||||
|
||||
use deltachat::contact::Contact;
|
||||
use deltachat::context::Context;
|
||||
use deltachat::dc_tools::{as_path, as_str, dc_strdup, to_string, OsStrExt, StrExt};
|
||||
use deltachat::dc_tools::{
|
||||
as_path, as_str, dc_strdup, to_string, to_string_lossy, OsStrExt, StrExt,
|
||||
};
|
||||
use deltachat::*;
|
||||
|
||||
// as C lacks a good and portable error handling,
|
||||
@@ -186,7 +188,7 @@ pub unsafe extern "C" fn dc_context_new(
|
||||
let os_name = if os_name.is_null() {
|
||||
String::from("DcFFI")
|
||||
} else {
|
||||
dc_tools::to_string_lossy(os_name)
|
||||
to_string_lossy(os_name)
|
||||
};
|
||||
let ffi_ctx = ContextWrapper {
|
||||
cb,
|
||||
@@ -735,7 +737,7 @@ pub unsafe extern "C" fn dc_send_text_msg(
|
||||
return 0;
|
||||
}
|
||||
let ffi_context = &*context;
|
||||
let text_to_send = dc_tools::to_string_lossy(text_to_send);
|
||||
let text_to_send = to_string_lossy(text_to_send);
|
||||
ffi_context
|
||||
.with_inner(|ctx| {
|
||||
chat::send_text_msg(ctx, chat_id, text_to_send)
|
||||
@@ -2861,7 +2863,7 @@ fn as_opt_str<'a>(s: *const libc::c_char) -> Option<&'a str> {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(dc_tools::as_str(s))
|
||||
Some(as_str(s))
|
||||
}
|
||||
|
||||
pub mod providers;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::ffi::CString;
|
||||
use std::path::Path;
|
||||
use std::ptr;
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -20,8 +20,8 @@ use deltachat::message::{self, Message, MessageState};
|
||||
use deltachat::peerstate::*;
|
||||
use deltachat::qr::*;
|
||||
use deltachat::sql;
|
||||
use deltachat::x::*;
|
||||
use deltachat::Event;
|
||||
use libc::free;
|
||||
|
||||
/// Reset database tables. This function is called from Core cmdline.
|
||||
/// Argument is a bitmask, executing single or multiple actions in one call.
|
||||
@@ -94,24 +94,20 @@ pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 {
|
||||
1
|
||||
}
|
||||
|
||||
unsafe fn dc_poke_eml_file(context: &Context, filename: *const libc::c_char) -> libc::c_int {
|
||||
/* mainly for testing, may be called by dc_import_spec() */
|
||||
let mut success: libc::c_int = 0i32;
|
||||
let mut data: *mut libc::c_char = ptr::null_mut();
|
||||
let mut data_bytes = 0;
|
||||
if !(dc_read_file(
|
||||
context,
|
||||
filename,
|
||||
&mut data as *mut *mut libc::c_char as *mut *mut libc::c_void,
|
||||
&mut data_bytes,
|
||||
) == 0i32)
|
||||
{
|
||||
dc_receive_imf(context, data, data_bytes, "import", 0, 0);
|
||||
success = 1;
|
||||
}
|
||||
free(data as *mut libc::c_void);
|
||||
fn dc_poke_eml_file(context: &Context, filename: impl AsRef<Path>) -> Result<(), Error> {
|
||||
let data = dc_read_file(context, filename)?;
|
||||
|
||||
success
|
||||
unsafe {
|
||||
dc_receive_imf(
|
||||
context,
|
||||
data.as_ptr() as *const _,
|
||||
data.len(),
|
||||
"import",
|
||||
0,
|
||||
0,
|
||||
)
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Import a file to the database.
|
||||
@@ -130,16 +126,16 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
|
||||
|
||||
let ok_to_continue;
|
||||
let mut success: libc::c_int = 0;
|
||||
let real_spec: *mut libc::c_char;
|
||||
let real_spec: String;
|
||||
let mut suffix: *mut libc::c_char = ptr::null_mut();
|
||||
let mut read_cnt: libc::c_int = 0;
|
||||
|
||||
/* if `spec` is given, remember it for later usage; if it is not given, try to use the last one */
|
||||
if !spec.is_null() {
|
||||
real_spec = dc_strdup(spec);
|
||||
real_spec = to_string(spec);
|
||||
context
|
||||
.sql
|
||||
.set_config(context, "import_spec", Some(as_str(real_spec)))
|
||||
.set_config(context, "import_spec", Some(&real_spec))
|
||||
.unwrap();
|
||||
ok_to_continue = true;
|
||||
} else {
|
||||
@@ -150,27 +146,24 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
|
||||
} else {
|
||||
ok_to_continue = true;
|
||||
}
|
||||
real_spec = rs.unwrap_or_default().strdup();
|
||||
real_spec = rs.unwrap_or_default();
|
||||
}
|
||||
if ok_to_continue {
|
||||
let ok_to_continue2;
|
||||
suffix = dc_get_filesuffix_lc(as_str(real_spec));
|
||||
if !suffix.is_null() && strcmp(suffix, b"eml\x00" as *const u8 as *const libc::c_char) == 0
|
||||
suffix = dc_get_filesuffix_lc(&real_spec);
|
||||
if !suffix.is_null()
|
||||
&& libc::strcmp(suffix, b"eml\x00" as *const u8 as *const libc::c_char) == 0
|
||||
{
|
||||
if 0 != dc_poke_eml_file(context, real_spec) {
|
||||
if dc_poke_eml_file(context, &real_spec).is_ok() {
|
||||
read_cnt += 1
|
||||
}
|
||||
ok_to_continue2 = true;
|
||||
} else {
|
||||
/* import a directory */
|
||||
let dir_name = std::path::Path::new(as_str(real_spec));
|
||||
let dir_name = std::path::Path::new(&real_spec);
|
||||
let dir = std::fs::read_dir(dir_name);
|
||||
if dir.is_err() {
|
||||
error!(
|
||||
context,
|
||||
"Import: Cannot open directory \"{}\".",
|
||||
as_str(real_spec),
|
||||
);
|
||||
error!(context, "Import: Cannot open directory \"{}\".", &real_spec,);
|
||||
ok_to_continue2 = false;
|
||||
} else {
|
||||
let dir = dir.unwrap();
|
||||
@@ -182,10 +175,9 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
|
||||
let name_f = entry.file_name();
|
||||
let name = name_f.to_string_lossy();
|
||||
if name.ends_with(".eml") {
|
||||
let path_plus_name = format!("{}/{}", as_str(real_spec), name);
|
||||
let path_plus_name = format!("{}/{}", &real_spec, name);
|
||||
info!(context, "Import: {}", path_plus_name);
|
||||
let path_plus_name_c = CString::yolo(path_plus_name);
|
||||
if 0 != dc_poke_eml_file(context, path_plus_name_c.as_ptr()) {
|
||||
if dc_poke_eml_file(context, path_plus_name).is_ok() {
|
||||
read_cnt += 1
|
||||
}
|
||||
}
|
||||
@@ -196,9 +188,7 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
|
||||
if ok_to_continue2 {
|
||||
info!(
|
||||
context,
|
||||
"Import: {} items read from \"{}\".",
|
||||
read_cnt,
|
||||
as_str(real_spec)
|
||||
"Import: {} items read from \"{}\".", read_cnt, &real_spec
|
||||
);
|
||||
if read_cnt > 0 {
|
||||
context.call_cb(Event::MsgsChanged {
|
||||
@@ -210,7 +200,6 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
|
||||
}
|
||||
}
|
||||
|
||||
free(real_spec as *mut libc::c_void);
|
||||
free(suffix as *mut libc::c_void);
|
||||
success
|
||||
}
|
||||
@@ -1017,7 +1006,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
"fileinfo" => {
|
||||
ensure!(!arg1.is_empty(), "Argument <file> missing.");
|
||||
|
||||
if let Some(buf) = dc_read_file_safe(context, &arg1) {
|
||||
if let Ok(buf) = dc_read_file(context, &arg1) {
|
||||
let (width, height) = dc_get_filemeta(&buf)?;
|
||||
println!("width={}, height={}", width, height);
|
||||
} else {
|
||||
|
||||
@@ -23,11 +23,9 @@ use std::sync::{Arc, Mutex, RwLock};
|
||||
use deltachat::config;
|
||||
use deltachat::configure::*;
|
||||
use deltachat::context::*;
|
||||
use deltachat::dc_tools::*;
|
||||
use deltachat::job::*;
|
||||
use deltachat::oauth2::*;
|
||||
use deltachat::securejoin::*;
|
||||
use deltachat::x::*;
|
||||
use deltachat::Event;
|
||||
use rustyline::completion::{Completer, FilenameCompleter, Pair};
|
||||
use rustyline::config::OutputStreamType;
|
||||
@@ -441,11 +439,6 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
|
||||
let mut args = line.splitn(2, ' ');
|
||||
let arg0 = args.next().unwrap_or_default();
|
||||
let arg1 = args.next().unwrap_or_default();
|
||||
let arg1_c = if arg1.is_empty() {
|
||||
std::ptr::null()
|
||||
} else {
|
||||
arg1.strdup()
|
||||
};
|
||||
|
||||
match arg0 {
|
||||
"connect" => {
|
||||
@@ -521,8 +514,6 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
|
||||
_ => dc_cmdline(&ctx.read().unwrap(), line)?,
|
||||
}
|
||||
|
||||
free(arg1_c as *mut _);
|
||||
|
||||
Ok(ExitResult::Continue)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use libc::free;
|
||||
use quick_xml;
|
||||
use quick_xml::events::{BytesEnd, BytesStart, BytesText};
|
||||
|
||||
@@ -5,7 +6,6 @@ use crate::constants::*;
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::*;
|
||||
use crate::login_param::LoginParam;
|
||||
use crate::x::*;
|
||||
|
||||
use super::read_autoconf_file;
|
||||
/* ******************************************************************************
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use std::ptr;
|
||||
|
||||
use libc::free;
|
||||
use quick_xml;
|
||||
use quick_xml::events::{BytesEnd, BytesStart, BytesText};
|
||||
|
||||
@@ -5,8 +8,6 @@ use crate::constants::*;
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::*;
|
||||
use crate::login_param::LoginParam;
|
||||
use crate::x::*;
|
||||
use std::ptr;
|
||||
|
||||
use super::read_autoconf_file;
|
||||
/* ******************************************************************************
|
||||
@@ -46,7 +47,7 @@ pub unsafe fn outlk_autodiscover(
|
||||
ok_to_continue = true;
|
||||
break;
|
||||
}
|
||||
memset(
|
||||
libc::memset(
|
||||
&mut outlk_ad as *mut outlk_autodiscover_t as *mut libc::c_void,
|
||||
0,
|
||||
::std::mem::size_of::<outlk_autodiscover_t>(),
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::ffi::CString;
|
||||
use std::path::Path;
|
||||
use std::ptr;
|
||||
|
||||
use libc::{free, strcmp, strlen, strstr};
|
||||
use mmime::mailmime_content::*;
|
||||
use mmime::mmapstring::*;
|
||||
use mmime::other::*;
|
||||
@@ -23,7 +24,6 @@ use crate::param::*;
|
||||
use crate::pgp::*;
|
||||
use crate::sql::{self, Sql};
|
||||
use crate::stock::StockMessage;
|
||||
use crate::x::*;
|
||||
|
||||
// import/export and tools
|
||||
// param1 is a directory where the keys are written to
|
||||
@@ -276,7 +276,7 @@ pub unsafe fn dc_continue_key_transfer(
|
||||
}
|
||||
|
||||
if let Some(filename) = msg.get_file(context) {
|
||||
if let Some(buf) = dc_read_file_safe(context, filename) {
|
||||
if let Ok(buf) = dc_read_file(context, filename) {
|
||||
norm_sc = dc_normalize_setup_code(context, setup_code);
|
||||
if norm_sc.is_null() {
|
||||
warn!(context, "Cannot normalize Setup Code.",);
|
||||
@@ -767,8 +767,8 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> bool {
|
||||
} else {
|
||||
info!(context, "EXPORTing filename={}", name);
|
||||
let curr_pathNfilename = context.get_blobdir().join(entry.file_name());
|
||||
if let Some(buf) =
|
||||
dc_read_file_safe(context, &curr_pathNfilename)
|
||||
if let Ok(buf) =
|
||||
dc_read_file(context, &curr_pathNfilename)
|
||||
{
|
||||
if buf.is_empty() {
|
||||
continue;
|
||||
@@ -874,7 +874,7 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
|
||||
free(buf.cast());
|
||||
buf = ptr::null_mut();
|
||||
|
||||
if let Some(buf_r) = dc_read_file_safe(context, &path_plus_name) {
|
||||
if let Ok(buf_r) = dc_read_file(context, &path_plus_name) {
|
||||
buf = buf_r.as_ptr() as *mut _;
|
||||
std::mem::forget(buf_r);
|
||||
} else {
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::path::Path;
|
||||
use std::ptr;
|
||||
|
||||
use chrono::TimeZone;
|
||||
use libc::{free, strcmp, strlen};
|
||||
use mmime::clist::*;
|
||||
use mmime::mailimf_types::*;
|
||||
use mmime::mailimf_types_helper::*;
|
||||
@@ -25,7 +26,6 @@ use crate::location;
|
||||
use crate::message::{self, Message};
|
||||
use crate::param::*;
|
||||
use crate::stock::StockMessage;
|
||||
use crate::x::*;
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub enum Loaded {
|
||||
|
||||
@@ -4,6 +4,7 @@ use std::ptr;
|
||||
|
||||
use charset::Charset;
|
||||
use deltachat_derive::{FromSql, ToSql};
|
||||
use libc::{strcmp, strlen, strncmp};
|
||||
use mmime::clist::*;
|
||||
use mmime::mailimf::*;
|
||||
use mmime::mailimf_types::*;
|
||||
@@ -25,7 +26,6 @@ use crate::error::Error;
|
||||
use crate::location;
|
||||
use crate::param::*;
|
||||
use crate::stock::StockMessage;
|
||||
use crate::x::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MimeParser<'a> {
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
use itertools::join;
|
||||
use libc::{free, strcmp, strlen};
|
||||
use mmime::clist::*;
|
||||
use mmime::mailimf::*;
|
||||
use mmime::mailimf_types::*;
|
||||
@@ -28,7 +29,6 @@ use crate::peerstate::*;
|
||||
use crate::securejoin::handle_securejoin_handshake;
|
||||
use crate::sql;
|
||||
use crate::stock::StockMessage;
|
||||
use crate::x::*;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
enum CreateEvent {
|
||||
|
||||
@@ -3,13 +3,13 @@ use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
use charset::Charset;
|
||||
use libc::{free, strlen};
|
||||
use mmime::mailmime_decode::*;
|
||||
use mmime::mmapstring::*;
|
||||
use mmime::other::*;
|
||||
use percent_encoding::{percent_decode, utf8_percent_encode, AsciiSet, CONTROLS};
|
||||
|
||||
use crate::dc_tools::*;
|
||||
use crate::x::*;
|
||||
|
||||
/**
|
||||
* Encode non-ascii-strings as `=?UTF-8?Q?Bj=c3=b6rn_Petersen?=`.
|
||||
@@ -336,6 +336,8 @@ unsafe fn print_hex(target: *mut libc::c_char, cur: *const libc::c_char) {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use libc::{strcmp, strncmp};
|
||||
use std::ffi::CStr;
|
||||
|
||||
#[test]
|
||||
|
||||
505
src/dc_tools.rs
505
src/dc_tools.rs
@@ -9,16 +9,15 @@ use std::time::SystemTime;
|
||||
use std::{fmt, fs, ptr};
|
||||
|
||||
use chrono::{Local, TimeZone};
|
||||
use libc::uintptr_t;
|
||||
use libc::{free, memcpy, strcpy, strlen, strstr, uintptr_t};
|
||||
use mmime::clist::*;
|
||||
use mmime::mailimf_types::*;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::error::Error;
|
||||
use crate::x::*;
|
||||
|
||||
pub fn dc_exactly_one_bit_set(v: libc::c_int) -> bool {
|
||||
pub(crate) fn dc_exactly_one_bit_set(v: libc::c_int) -> bool {
|
||||
0 != v && 0 == v & (v - 1)
|
||||
}
|
||||
|
||||
@@ -43,7 +42,7 @@ pub unsafe fn dc_strdup(s: *const libc::c_char) -> *mut libc::c_char {
|
||||
ret = strdup(s);
|
||||
assert!(!ret.is_null());
|
||||
} else {
|
||||
ret = calloc(1, 1) as *mut libc::c_char;
|
||||
ret = libc::calloc(1, 1) as *mut libc::c_char;
|
||||
assert!(!ret.is_null());
|
||||
}
|
||||
|
||||
@@ -51,21 +50,7 @@ pub unsafe fn dc_strdup(s: *const libc::c_char) -> *mut libc::c_char {
|
||||
}
|
||||
|
||||
/// Duplicates a string, returns null if given string is null
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use deltachat::dc_tools::{dc_strdup_keep_null, to_string};
|
||||
/// use std::ffi::{CStr};
|
||||
///
|
||||
/// unsafe {
|
||||
/// let str_a = b"foobar\x00" as *const u8 as *const libc::c_char;
|
||||
/// let str_a_copy = dc_strdup_keep_null(str_a);
|
||||
/// assert_eq!(to_string(str_a_copy), "foobar");
|
||||
/// assert_ne!(str_a, str_a_copy);
|
||||
/// }
|
||||
/// ```
|
||||
pub unsafe fn dc_strdup_keep_null(s: *const libc::c_char) -> *mut libc::c_char {
|
||||
pub(crate) unsafe fn dc_strdup_keep_null(s: *const libc::c_char) -> *mut libc::c_char {
|
||||
if !s.is_null() {
|
||||
dc_strdup(s)
|
||||
} else {
|
||||
@@ -73,7 +58,7 @@ pub unsafe fn dc_strdup_keep_null(s: *const libc::c_char) -> *mut libc::c_char {
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn dc_atoi_null_is_0(s: *const libc::c_char) -> libc::c_int {
|
||||
pub(crate) fn dc_atoi_null_is_0(s: *const libc::c_char) -> libc::c_int {
|
||||
if !s.is_null() {
|
||||
as_str(s).parse().unwrap_or_default()
|
||||
} else {
|
||||
@@ -81,20 +66,6 @@ pub unsafe fn dc_atoi_null_is_0(s: *const libc::c_char) -> libc::c_int {
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn dc_str_replace(
|
||||
haystack: *mut *mut libc::c_char,
|
||||
needle: *const libc::c_char,
|
||||
replacement: *const libc::c_char,
|
||||
) {
|
||||
let haystack_s = to_string(*haystack);
|
||||
let needle_s = to_string(needle);
|
||||
let replacement_s = to_string(replacement);
|
||||
|
||||
free(*haystack as *mut libc::c_void);
|
||||
|
||||
*haystack = haystack_s.replace(&needle_s, &replacement_s).strdup();
|
||||
}
|
||||
|
||||
unsafe fn dc_ltrim(buf: *mut libc::c_char) {
|
||||
let mut len: libc::size_t;
|
||||
let mut cur: *const libc::c_uchar;
|
||||
@@ -106,7 +77,7 @@ unsafe fn dc_ltrim(buf: *mut libc::c_char) {
|
||||
len = len.wrapping_sub(1)
|
||||
}
|
||||
if buf as *const libc::c_uchar != cur {
|
||||
memmove(
|
||||
libc::memmove(
|
||||
buf as *mut libc::c_void,
|
||||
cur as *const libc::c_void,
|
||||
len.wrapping_add(1),
|
||||
@@ -137,28 +108,13 @@ unsafe fn dc_rtrim(buf: *mut libc::c_char) {
|
||||
};
|
||||
}
|
||||
|
||||
pub unsafe fn dc_trim(buf: *mut libc::c_char) {
|
||||
pub(crate) unsafe fn dc_trim(buf: *mut libc::c_char) {
|
||||
dc_ltrim(buf);
|
||||
dc_rtrim(buf);
|
||||
}
|
||||
|
||||
/* the result must be free()'d */
|
||||
pub unsafe fn dc_null_terminate(
|
||||
in_0: *const libc::c_char,
|
||||
bytes: libc::c_int,
|
||||
) -> *mut libc::c_char {
|
||||
let out: *mut libc::c_char = malloc(bytes as usize + 1) as *mut libc::c_char;
|
||||
assert!(!out.is_null());
|
||||
if !in_0.is_null() && bytes > 0 {
|
||||
strncpy(out, in_0, bytes as usize);
|
||||
}
|
||||
*out.offset(bytes as isize) = 0 as libc::c_char;
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
/* remove all \r characters from string */
|
||||
pub unsafe fn dc_remove_cr_chars(buf: *mut libc::c_char) {
|
||||
pub(crate) unsafe fn dc_remove_cr_chars(buf: *mut libc::c_char) {
|
||||
/* search for first `\r` */
|
||||
let mut p1: *const libc::c_char = buf;
|
||||
while 0 != *p1 {
|
||||
@@ -179,84 +135,9 @@ pub unsafe fn dc_remove_cr_chars(buf: *mut libc::c_char) {
|
||||
*p2 = 0 as libc::c_char;
|
||||
}
|
||||
|
||||
/* replace bad UTF-8 characters by sequences of `_` (to avoid problems in filenames, we do not use eg. `?`) the function is useful if strings are unexpectingly encoded eg. as ISO-8859-1 */
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe fn dc_replace_bad_utf8_chars(buf: *mut libc::c_char) {
|
||||
let mut OK_TO_CONTINUE = true;
|
||||
if buf.is_null() {
|
||||
return;
|
||||
}
|
||||
/* force unsigned - otherwise the `> ' '` comparison will fail */
|
||||
let mut p1: *mut libc::c_uchar = buf as *mut libc::c_uchar;
|
||||
let p1len: libc::c_int = strlen(buf) as libc::c_int;
|
||||
let mut c: libc::c_int;
|
||||
let mut i: libc::c_int;
|
||||
let ix: libc::c_int;
|
||||
let mut n: libc::c_int;
|
||||
let mut j: libc::c_int;
|
||||
i = 0;
|
||||
ix = p1len;
|
||||
's_36: loop {
|
||||
if !(i < ix) {
|
||||
break;
|
||||
}
|
||||
c = *p1.offset(i as isize) as libc::c_int;
|
||||
if c > 0 && c <= 0x7f {
|
||||
n = 0
|
||||
} else if c & 0xe0 == 0xc0 {
|
||||
n = 1
|
||||
} else if c == 0xed
|
||||
&& i < ix - 1
|
||||
&& *p1.offset((i + 1) as isize) as libc::c_int & 0xa0 == 0xa0
|
||||
{
|
||||
/* U+d800 to U+dfff */
|
||||
OK_TO_CONTINUE = false;
|
||||
break;
|
||||
} else if c & 0xf0 == 0xe0 {
|
||||
n = 2
|
||||
} else if c & 0xf8 == 0xf0 {
|
||||
n = 3
|
||||
} else {
|
||||
//else if ((c & 0xFC) == 0xF8) { n=4; } /* 111110bb - not valid in https://tools.ietf.org/html/rfc3629 */
|
||||
//else if ((c & 0xFE) == 0xFC) { n=5; } /* 1111110b - not valid in https://tools.ietf.org/html/rfc3629 */
|
||||
OK_TO_CONTINUE = false;
|
||||
break;
|
||||
}
|
||||
j = 0;
|
||||
while j < n && i < ix {
|
||||
/* n bytes matching 10bbbbbb follow ? */
|
||||
i += 1;
|
||||
if i == ix || *p1.offset(i as isize) as libc::c_int & 0xc0 != 0x80 {
|
||||
OK_TO_CONTINUE = false;
|
||||
break 's_36;
|
||||
}
|
||||
j += 1
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
if OK_TO_CONTINUE == false {
|
||||
while 0 != *p1 {
|
||||
if *p1 as libc::c_int > 0x7f {
|
||||
*p1 = '_' as i32 as libc::c_uchar
|
||||
}
|
||||
p1 = p1.offset(1isize)
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// Shortens a string to a specified length and adds "..." or "[...]" to the end of
|
||||
/// the shortened string.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use deltachat::dc_tools::dc_truncate;
|
||||
///
|
||||
/// let s = "this is a little test string";
|
||||
/// assert_eq!(dc_truncate(s, 16, false), "this is a [...]");
|
||||
/// assert_eq!(dc_truncate(s, 16, true), "this is a ...");
|
||||
/// ```
|
||||
pub fn dc_truncate(buf: &str, approx_chars: usize, do_unwrap: bool) -> Cow<str> {
|
||||
pub(crate) fn dc_truncate(buf: &str, approx_chars: usize, do_unwrap: bool) -> Cow<str> {
|
||||
let ellipse = if do_unwrap { "..." } else { "[...]" };
|
||||
|
||||
let count = buf.chars().count();
|
||||
@@ -278,7 +159,7 @@ pub fn dc_truncate(buf: &str, approx_chars: usize, do_unwrap: bool) -> Cow<str>
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe fn dc_truncate_n_unwrap_str(
|
||||
pub(crate) unsafe fn dc_truncate_n_unwrap_str(
|
||||
buf: *mut libc::c_char,
|
||||
approx_characters: libc::c_int,
|
||||
do_unwrap: libc::c_int,
|
||||
@@ -337,7 +218,7 @@ unsafe fn dc_utf8_strnlen(s: *const libc::c_char, n: libc::size_t) -> libc::size
|
||||
j
|
||||
}
|
||||
|
||||
pub unsafe fn dc_str_from_clist(
|
||||
pub(crate) unsafe fn dc_str_from_clist(
|
||||
list: *const clist,
|
||||
delimiter: *const libc::c_char,
|
||||
) -> *mut libc::c_char {
|
||||
@@ -369,7 +250,7 @@ pub unsafe fn dc_str_from_clist(
|
||||
res.strdup()
|
||||
}
|
||||
|
||||
pub unsafe fn dc_str_to_clist(
|
||||
pub(crate) unsafe fn dc_str_to_clist(
|
||||
str: *const libc::c_char,
|
||||
delimiter: *const libc::c_char,
|
||||
) -> *mut clist {
|
||||
@@ -408,7 +289,7 @@ const COLORS: [u32; 16] = [
|
||||
0x39b249, 0xbb243b, 0x964078, 0x66874f, 0x308ab9, 0x127ed0, 0xbe450c,
|
||||
];
|
||||
|
||||
pub fn dc_str_to_color(s: impl AsRef<str>) -> u32 {
|
||||
pub(crate) fn dc_str_to_color(s: impl AsRef<str>) -> u32 {
|
||||
let str_lower = s.as_ref().to_lowercase();
|
||||
let mut checksum = 0;
|
||||
let bytes = str_lower.as_bytes();
|
||||
@@ -422,8 +303,9 @@ pub fn dc_str_to_color(s: impl AsRef<str>) -> u32 {
|
||||
}
|
||||
|
||||
/* clist tools */
|
||||
|
||||
/* calls free() for each item content */
|
||||
pub unsafe fn clist_free_content(haystack: *const clist) {
|
||||
pub(crate) unsafe fn clist_free_content(haystack: *const clist) {
|
||||
let mut iter = (*haystack).first;
|
||||
|
||||
while !iter.is_null() {
|
||||
@@ -437,7 +319,7 @@ pub unsafe fn clist_free_content(haystack: *const clist) {
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn clist_search_string_nocase(
|
||||
pub(crate) unsafe fn clist_search_string_nocase(
|
||||
haystack: *const clist,
|
||||
needle: *const libc::c_char,
|
||||
) -> bool {
|
||||
@@ -448,7 +330,7 @@ pub unsafe fn clist_search_string_nocase(
|
||||
|
||||
/* date/time tools */
|
||||
/* the result is UTC or DC_INVALID_TIMESTAMP */
|
||||
pub unsafe fn dc_timestamp_from_date(date_time: *mut mailimf_date_time) -> i64 {
|
||||
pub(crate) unsafe fn dc_timestamp_from_date(date_time: *mut mailimf_date_time) -> i64 {
|
||||
let sec = (*date_time).dt_sec;
|
||||
let min = (*date_time).dt_min;
|
||||
let hour = (*date_time).dt_hour;
|
||||
@@ -482,13 +364,13 @@ pub fn dc_timestamp_to_str(wanted: i64) -> String {
|
||||
ts.format("%Y.%m.%d %H:%M:%S").to_string()
|
||||
}
|
||||
|
||||
pub fn dc_gm2local_offset() -> i64 {
|
||||
pub(crate) fn dc_gm2local_offset() -> i64 {
|
||||
let lt = Local::now();
|
||||
((lt.offset().local_minus_utc() / (60 * 60)) * 100) as i64
|
||||
}
|
||||
|
||||
/* timesmearing */
|
||||
pub fn dc_smeared_time(context: &Context) -> i64 {
|
||||
pub(crate) fn dc_smeared_time(context: &Context) -> i64 {
|
||||
/* function returns a corrected time(NULL) */
|
||||
let mut now = time();
|
||||
let ts = *context.last_smeared_timestamp.clone().read().unwrap();
|
||||
@@ -499,7 +381,7 @@ pub fn dc_smeared_time(context: &Context) -> i64 {
|
||||
now
|
||||
}
|
||||
|
||||
pub fn dc_create_smeared_timestamp(context: &Context) -> i64 {
|
||||
pub(crate) fn dc_create_smeared_timestamp(context: &Context) -> i64 {
|
||||
let now = time();
|
||||
let mut ret = now;
|
||||
|
||||
@@ -514,7 +396,7 @@ pub fn dc_create_smeared_timestamp(context: &Context) -> i64 {
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn dc_create_smeared_timestamps(context: &Context, count: usize) -> i64 {
|
||||
pub(crate) fn dc_create_smeared_timestamps(context: &Context, count: usize) -> i64 {
|
||||
/* get a range to timestamps that can be used uniquely */
|
||||
let now = time();
|
||||
let start = now + (if count < 5 { count } else { 5 }) as i64 - count as i64;
|
||||
@@ -528,7 +410,7 @@ pub fn dc_create_smeared_timestamps(context: &Context, count: usize) -> i64 {
|
||||
}
|
||||
|
||||
/* Message-ID tools */
|
||||
pub fn dc_create_id() -> String {
|
||||
pub(crate) fn dc_create_id() -> String {
|
||||
/* generate an id. the generated ID should be as short and as unique as possible:
|
||||
- short, because it may also used as part of Message-ID headers or in QR codes
|
||||
- unique as two IDs generated on two devices should not be the same. However, collisions are not world-wide but only by the few contacts.
|
||||
@@ -568,7 +450,7 @@ fn encode_66bits_as_base64(v1: u32, v2: u32, fill: u32) -> String {
|
||||
String::from_utf8(wrapped_writer).unwrap()
|
||||
}
|
||||
|
||||
pub fn dc_create_incoming_rfc724_mid(
|
||||
pub(crate) fn dc_create_incoming_rfc724_mid(
|
||||
message_timestamp: i64,
|
||||
contact_id_from: u32,
|
||||
contact_ids_to: &Vec<u32>,
|
||||
@@ -590,7 +472,7 @@ pub fn dc_create_incoming_rfc724_mid(
|
||||
/// - this function is called for all outgoing messages.
|
||||
/// - the message ID should be globally unique
|
||||
/// - do not add a counter or any private data as this leaks information unncessarily
|
||||
pub fn dc_create_outgoing_rfc724_mid(grpid: Option<&str>, from_addr: &str) -> String {
|
||||
pub(crate) fn dc_create_outgoing_rfc724_mid(grpid: Option<&str>, from_addr: &str) -> String {
|
||||
let hostname = from_addr
|
||||
.find('@')
|
||||
.map(|k| &from_addr[k..])
|
||||
@@ -606,16 +488,7 @@ pub fn dc_create_outgoing_rfc724_mid(grpid: Option<&str>, from_addr: &str) -> St
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `mid` - A string that holds the message id
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use deltachat::dc_tools::dc_extract_grpid_from_rfc724_mid;
|
||||
/// let mid = "Gr.12345678901.morerandom@domain.de";
|
||||
/// let grpid = dc_extract_grpid_from_rfc724_mid(mid);
|
||||
/// assert_eq!(grpid, Some("12345678901"));
|
||||
/// ```
|
||||
pub fn dc_extract_grpid_from_rfc724_mid(mid: &str) -> Option<&str> {
|
||||
pub(crate) fn dc_extract_grpid_from_rfc724_mid(mid: &str) -> Option<&str> {
|
||||
if mid.len() < 9 || !mid.starts_with("Gr.") {
|
||||
return None;
|
||||
}
|
||||
@@ -632,7 +505,9 @@ pub fn dc_extract_grpid_from_rfc724_mid(mid: &str) -> Option<&str> {
|
||||
None
|
||||
}
|
||||
|
||||
pub unsafe fn dc_extract_grpid_from_rfc724_mid_list(list: *const clist) -> *mut libc::c_char {
|
||||
pub(crate) unsafe fn dc_extract_grpid_from_rfc724_mid_list(
|
||||
list: *const clist,
|
||||
) -> *mut libc::c_char {
|
||||
if !list.is_null() {
|
||||
let mut cur: *mut clistiter = (*list).first;
|
||||
while !cur.is_null() {
|
||||
@@ -656,7 +531,7 @@ pub unsafe fn dc_extract_grpid_from_rfc724_mid_list(list: *const clist) -> *mut
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
pub fn dc_ensure_no_slash_safe(path: &str) -> &str {
|
||||
pub(crate) fn dc_ensure_no_slash_safe(path: &str) -> &str {
|
||||
if path.ends_with('/') || path.ends_with('\\') {
|
||||
return &path[..path.len() - 1];
|
||||
}
|
||||
@@ -671,14 +546,6 @@ fn validate_filename(filename: &str) -> String {
|
||||
.replace(':', "-")
|
||||
}
|
||||
|
||||
pub unsafe fn dc_get_filename(path_filename: impl AsRef<str>) -> *mut libc::c_char {
|
||||
if let Some(p) = Path::new(path_filename.as_ref()).file_name() {
|
||||
p.to_string_lossy().strdup()
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
||||
// the returned suffix is lower-case
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe fn dc_get_filesuffix_lc(path_filename: impl AsRef<str>) -> *mut libc::c_char {
|
||||
@@ -700,7 +567,7 @@ pub fn dc_get_filemeta(buf: &[u8]) -> Result<(u32, u32), Error> {
|
||||
///
|
||||
/// If `path` starts with "$BLOBDIR", replaces it with the blobdir path.
|
||||
/// Otherwise, returns path as is.
|
||||
pub fn dc_get_abs_path<P: AsRef<std::path::Path>>(
|
||||
pub(crate) fn dc_get_abs_path<P: AsRef<std::path::Path>>(
|
||||
context: &Context,
|
||||
path: P,
|
||||
) -> std::path::PathBuf {
|
||||
@@ -712,11 +579,11 @@ pub fn dc_get_abs_path<P: AsRef<std::path::Path>>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dc_file_exist(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
||||
pub(crate) fn dc_file_exist(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
||||
dc_get_abs_path(context, &path).exists()
|
||||
}
|
||||
|
||||
pub fn dc_get_filebytes(context: &Context, path: impl AsRef<std::path::Path>) -> u64 {
|
||||
pub(crate) fn dc_get_filebytes(context: &Context, path: impl AsRef<std::path::Path>) -> u64 {
|
||||
let path_abs = dc_get_abs_path(context, &path);
|
||||
match fs::metadata(&path_abs) {
|
||||
Ok(meta) => meta.len() as u64,
|
||||
@@ -724,7 +591,7 @@ pub fn dc_get_filebytes(context: &Context, path: impl AsRef<std::path::Path>) ->
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dc_delete_file(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
||||
pub(crate) fn dc_delete_file(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
||||
let path_abs = dc_get_abs_path(context, &path);
|
||||
if !path_abs.is_file() {
|
||||
warn!(
|
||||
@@ -744,7 +611,7 @@ pub fn dc_delete_file(context: &Context, path: impl AsRef<std::path::Path>) -> b
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dc_copy_file(
|
||||
pub(crate) fn dc_copy_file(
|
||||
context: &Context,
|
||||
src: impl AsRef<std::path::Path>,
|
||||
dest: impl AsRef<std::path::Path>,
|
||||
@@ -765,7 +632,7 @@ pub fn dc_copy_file(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dc_create_folder(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
||||
pub(crate) fn dc_create_folder(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
||||
let path_abs = dc_get_abs_path(context, &path);
|
||||
if !path_abs.exists() {
|
||||
match fs::create_dir_all(path_abs) {
|
||||
@@ -785,7 +652,7 @@ pub fn dc_create_folder(context: &Context, path: impl AsRef<std::path::Path>) ->
|
||||
}
|
||||
|
||||
/// Write a the given content to provied file path.
|
||||
pub fn dc_write_file(context: &Context, path: impl AsRef<Path>, buf: &[u8]) -> bool {
|
||||
pub(crate) fn dc_write_file(context: &Context, path: impl AsRef<Path>, buf: &[u8]) -> bool {
|
||||
let path_abs = dc_get_abs_path(context, &path);
|
||||
if let Err(_err) = fs::write(&path_abs, buf) {
|
||||
warn!(
|
||||
@@ -800,42 +667,26 @@ pub fn dc_write_file(context: &Context, path: impl AsRef<Path>, buf: &[u8]) -> b
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe fn dc_read_file(
|
||||
pub fn dc_read_file<P: AsRef<std::path::Path>>(
|
||||
context: &Context,
|
||||
pathNfilename: *const libc::c_char,
|
||||
buf: *mut *mut libc::c_void,
|
||||
buf_bytes: *mut libc::size_t,
|
||||
) -> libc::c_int {
|
||||
if pathNfilename.is_null() {
|
||||
return 0;
|
||||
}
|
||||
if let Some(mut bytes) = dc_read_file_safe(context, as_str(pathNfilename)) {
|
||||
*buf = &mut bytes[..] as *mut _ as *mut libc::c_void;
|
||||
*buf_bytes = bytes.len();
|
||||
std::mem::forget(bytes);
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dc_read_file_safe<P: AsRef<std::path::Path>>(context: &Context, path: P) -> Option<Vec<u8>> {
|
||||
path: P,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let path_abs = dc_get_abs_path(context, &path);
|
||||
|
||||
match fs::read(&path_abs) {
|
||||
Ok(bytes) => Some(bytes),
|
||||
Err(_err) => {
|
||||
Ok(bytes) => Ok(bytes),
|
||||
Err(err) => {
|
||||
warn!(
|
||||
context,
|
||||
"Cannot read \"{}\" or file is empty.",
|
||||
path.as_ref().display()
|
||||
);
|
||||
None
|
||||
Err(err.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dc_get_fine_path_filename(
|
||||
pub(crate) fn dc_get_fine_path_filename(
|
||||
context: &Context,
|
||||
folder: impl AsRef<Path>,
|
||||
desired_filename_suffix: impl AsRef<str>,
|
||||
@@ -880,7 +731,7 @@ pub fn dc_get_fine_path_filename(
|
||||
panic!("Something is really wrong, you need to clean up your disk");
|
||||
}
|
||||
|
||||
pub fn dc_is_blobdir_path(context: &Context, path: impl AsRef<str>) -> bool {
|
||||
pub(crate) fn dc_is_blobdir_path(context: &Context, path: impl AsRef<str>) -> bool {
|
||||
context
|
||||
.get_blobdir()
|
||||
.to_str()
|
||||
@@ -900,7 +751,7 @@ fn dc_make_rel_path(context: &Context, path: &mut String) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dc_make_rel_and_copy(context: &Context, path: &mut String) -> bool {
|
||||
pub(crate) fn dc_make_rel_and_copy(context: &Context, path: &mut String) -> bool {
|
||||
if dc_is_blobdir_path(context, &path) {
|
||||
dc_make_rel_path(context, path);
|
||||
return true;
|
||||
@@ -1148,7 +999,7 @@ fn as_path_unicode<'a>(s: *const libc::c_char) -> &'a std::path::Path {
|
||||
std::path::Path::new(as_str(s))
|
||||
}
|
||||
|
||||
pub fn time() -> i64 {
|
||||
pub(crate) fn time() -> i64 {
|
||||
SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
@@ -1220,36 +1071,64 @@ impl FromStr for EmailAddress {
|
||||
|
||||
/// Utility to check if a in the binary represantion of listflags
|
||||
/// the bit at position bitindex is 1.
|
||||
///
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::TryInto;
|
||||
/// use deltachat::dc_tools::listflags_has;
|
||||
/// use deltachat::constants::{DC_GCL_ADD_SELF, DC_GCL_VERIFIED_ONLY};
|
||||
/// let listflags: u32 = 0x1101;
|
||||
/// assert!(listflags_has(listflags, 0x1) == true);
|
||||
/// assert!(listflags_has(listflags, 0x10) == false);
|
||||
/// assert!(listflags_has(listflags, 0x100) == true);
|
||||
/// assert!(listflags_has(listflags, 0x1000) == true);
|
||||
/// let listflags: u32 = (DC_GCL_ADD_SELF | DC_GCL_VERIFIED_ONLY).try_into().unwrap();
|
||||
/// assert!(listflags_has(listflags, DC_GCL_VERIFIED_ONLY) == true);
|
||||
/// assert!(listflags_has(listflags, DC_GCL_ADD_SELF) == true);
|
||||
/// let listflags: u32 = DC_GCL_VERIFIED_ONLY.try_into().unwrap();
|
||||
/// assert!(listflags_has(listflags, DC_GCL_ADD_SELF) == false);
|
||||
/// ```
|
||||
pub fn listflags_has(listflags: u32, bitindex: usize) -> bool {
|
||||
pub(crate) fn listflags_has(listflags: u32, bitindex: usize) -> bool {
|
||||
let listflags = listflags as usize;
|
||||
(listflags & bitindex) == bitindex
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char {
|
||||
if s.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
let slen = strlen(s);
|
||||
let result = libc::malloc(slen + 1);
|
||||
if result.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
memcpy(result, s as *const _, slen + 1);
|
||||
result as *mut _
|
||||
}
|
||||
|
||||
pub(crate) fn strndup(s: *const libc::c_char, n: libc::c_ulong) -> *mut libc::c_char {
|
||||
if s.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
let end = std::cmp::min(n as usize, unsafe { strlen(s) });
|
||||
unsafe {
|
||||
let result = libc::malloc(end + 1);
|
||||
memcpy(result, s as *const _, end);
|
||||
std::ptr::write_bytes(result.offset(end as isize), b'\x00', 1);
|
||||
|
||||
result as *mut _
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char) -> libc::c_int {
|
||||
let s1 = std::ffi::CStr::from_ptr(s1)
|
||||
.to_string_lossy()
|
||||
.to_lowercase();
|
||||
let s2 = std::ffi::CStr::from_ptr(s2)
|
||||
.to_string_lossy()
|
||||
.to_lowercase();
|
||||
if s1 == s2 {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use libc::strcmp;
|
||||
use std::convert::TryInto;
|
||||
use std::ffi::CStr;
|
||||
|
||||
use crate::constants::*;
|
||||
use crate::test_utils::*;
|
||||
|
||||
#[test]
|
||||
@@ -1348,23 +1227,6 @@ mod tests {
|
||||
assert_eq!("1.22", format!("{}", 1.22));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_str_replace() {
|
||||
unsafe {
|
||||
let mut str: *mut libc::c_char = strdup(b"aaa\x00" as *const u8 as *const libc::c_char);
|
||||
dc_str_replace(
|
||||
&mut str,
|
||||
b"a\x00" as *const u8 as *const libc::c_char,
|
||||
b"ab\x00" as *const u8 as *const libc::c_char,
|
||||
);
|
||||
assert_eq!(
|
||||
CStr::from_ptr(str as *const libc::c_char).to_str().unwrap(),
|
||||
"ababab"
|
||||
);
|
||||
free(str as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_truncate_1() {
|
||||
let s = "this is a little test string";
|
||||
@@ -1420,45 +1282,6 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_null_terminate_1() {
|
||||
unsafe {
|
||||
let str: *mut libc::c_char =
|
||||
dc_null_terminate(b"abcxyz\x00" as *const u8 as *const libc::c_char, 3);
|
||||
assert_eq!(
|
||||
CStr::from_ptr(str as *const libc::c_char).to_str().unwrap(),
|
||||
"abc"
|
||||
);
|
||||
free(str as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_null_terminate_2() {
|
||||
unsafe {
|
||||
let str: *mut libc::c_char =
|
||||
dc_null_terminate(b"abcxyz\x00" as *const u8 as *const libc::c_char, 0);
|
||||
assert_eq!(
|
||||
CStr::from_ptr(str as *const libc::c_char).to_str().unwrap(),
|
||||
""
|
||||
);
|
||||
free(str as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_null_terminate_3() {
|
||||
unsafe {
|
||||
let str: *mut libc::c_char =
|
||||
dc_null_terminate(0 as *const u8 as *const libc::c_char, 0);
|
||||
assert_eq!(
|
||||
CStr::from_ptr(str as *const libc::c_char).to_str().unwrap(),
|
||||
""
|
||||
);
|
||||
free(str as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_str_to_clist_1() {
|
||||
unsafe {
|
||||
@@ -1517,63 +1340,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_replace_bad_utf8_chars_1() {
|
||||
unsafe {
|
||||
let buf1 = strdup(b"ol\xc3\xa1 mundo <>\"\'& \xc3\xa4\xc3\x84\xc3\xb6\xc3\x96\xc3\xbc\xc3\x9c\xc3\x9f foo\xc3\x86\xc3\xa7\xc3\x87 \xe2\x99\xa6&noent;\x00" as *const u8 as *const libc::c_char);
|
||||
let buf2 = strdup(buf1);
|
||||
|
||||
dc_replace_bad_utf8_chars(buf2);
|
||||
|
||||
assert_eq!(strcmp(buf1, buf2), 0);
|
||||
|
||||
free(buf1 as *mut libc::c_void);
|
||||
free(buf2 as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_replace_bad_utf8_chars_2() {
|
||||
unsafe {
|
||||
let buf1 = strdup(b"ISO-String with Ae: \xc4\x00" as *const u8 as *const libc::c_char);
|
||||
let buf2 = strdup(buf1);
|
||||
|
||||
dc_replace_bad_utf8_chars(buf2);
|
||||
|
||||
assert_eq!(
|
||||
CStr::from_ptr(buf2 as *const libc::c_char)
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
"ISO-String with Ae: _"
|
||||
);
|
||||
|
||||
free(buf1 as *mut libc::c_void);
|
||||
free(buf2 as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_replace_bad_utf8_chars_3() {
|
||||
unsafe {
|
||||
let buf1 = strdup(b"\x00" as *const u8 as *const libc::c_char);
|
||||
let buf2 = strdup(buf1);
|
||||
|
||||
dc_replace_bad_utf8_chars(buf2);
|
||||
|
||||
assert_eq!(*buf2.offset(0), 0);
|
||||
|
||||
free(buf1 as *mut libc::c_void);
|
||||
free(buf2 as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_replace_bad_utf8_chars_4() {
|
||||
unsafe {
|
||||
dc_replace_bad_utf8_chars(ptr::null_mut());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_create_id() {
|
||||
let buf = dc_create_id();
|
||||
@@ -1809,4 +1575,85 @@ mod tests {
|
||||
dc_make_rel_path(&t.ctx, &mut foo);
|
||||
assert_eq!(foo, format!("$BLOBDIR{}foo", std::path::MAIN_SEPARATOR));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_strndup() {
|
||||
unsafe {
|
||||
let res = strndup(b"helloworld\x00" as *const u8 as *const libc::c_char, 4);
|
||||
assert_eq!(
|
||||
to_string(res),
|
||||
to_string(b"hell\x00" as *const u8 as *const libc::c_char)
|
||||
);
|
||||
assert_eq!(strlen(res), 4);
|
||||
free(res as *mut _);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file_handling() {
|
||||
let t = dummy_context();
|
||||
let context = &t.ctx;
|
||||
|
||||
if dc_file_exist(context, "$BLOBDIR/foobar")
|
||||
|| dc_file_exist(context, "$BLOBDIR/dada")
|
||||
|| dc_file_exist(context, "$BLOBDIR/foobar.dadada")
|
||||
|| dc_file_exist(context, "$BLOBDIR/foobar-folder")
|
||||
{
|
||||
dc_delete_file(context, "$BLOBDIR/foobar");
|
||||
dc_delete_file(context, "$BLOBDIR/dada");
|
||||
dc_delete_file(context, "$BLOBDIR/foobar.dadada");
|
||||
dc_delete_file(context, "$BLOBDIR/foobar-folder");
|
||||
}
|
||||
assert!(dc_write_file(context, "$BLOBDIR/foobar", b"content"));
|
||||
assert!(dc_file_exist(context, "$BLOBDIR/foobar",));
|
||||
assert!(!dc_file_exist(context, "$BLOBDIR/foobarx"));
|
||||
assert_eq!(dc_get_filebytes(context, "$BLOBDIR/foobar"), 7);
|
||||
|
||||
let abs_path = context
|
||||
.get_blobdir()
|
||||
.join("foobar")
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
|
||||
assert!(dc_is_blobdir_path(context, &abs_path));
|
||||
assert!(dc_is_blobdir_path(context, "$BLOBDIR/fofo",));
|
||||
assert!(!dc_is_blobdir_path(context, "/BLOBDIR/fofo",));
|
||||
assert!(dc_file_exist(context, &abs_path));
|
||||
|
||||
assert!(dc_copy_file(context, "$BLOBDIR/foobar", "$BLOBDIR/dada",));
|
||||
assert_eq!(dc_get_filebytes(context, "$BLOBDIR/dada",), 7);
|
||||
|
||||
let buf = dc_read_file(context, "$BLOBDIR/dada").unwrap();
|
||||
|
||||
assert_eq!(buf.len(), 7);
|
||||
assert_eq!(&buf, b"content");
|
||||
|
||||
assert!(dc_delete_file(context, "$BLOBDIR/foobar"));
|
||||
assert!(dc_delete_file(context, "$BLOBDIR/dada"));
|
||||
assert!(dc_create_folder(context, "$BLOBDIR/foobar-folder"));
|
||||
assert!(dc_file_exist(context, "$BLOBDIR/foobar-folder",));
|
||||
assert!(!dc_delete_file(context, "$BLOBDIR/foobar-folder"));
|
||||
let fn0 = dc_get_fine_path_filename(context, "$BLOBDIR", "foobar.dadada");
|
||||
assert_eq!(fn0, PathBuf::from("$BLOBDIR/foobar.dadada"));
|
||||
|
||||
assert!(dc_write_file(context, &fn0, b"content"));
|
||||
let fn1 = dc_get_fine_path_filename(context, "$BLOBDIR", "foobar.dadada");
|
||||
assert_eq!(fn1, PathBuf::from("$BLOBDIR/foobar-1.dadada"));
|
||||
|
||||
assert!(dc_delete_file(context, &fn0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_listflags_has() {
|
||||
let listflags: u32 = 0x1101;
|
||||
assert!(listflags_has(listflags, 0x1) == true);
|
||||
assert!(listflags_has(listflags, 0x10) == false);
|
||||
assert!(listflags_has(listflags, 0x100) == true);
|
||||
assert!(listflags_has(listflags, 0x1000) == true);
|
||||
let listflags: u32 = (DC_GCL_ADD_SELF | DC_GCL_VERIFIED_ONLY).try_into().unwrap();
|
||||
assert!(listflags_has(listflags, DC_GCL_VERIFIED_ONLY) == true);
|
||||
assert!(listflags_has(listflags, DC_GCL_ADD_SELF) == true);
|
||||
let listflags: u32 = DC_GCL_VERIFIED_ONLY.try_into().unwrap();
|
||||
assert!(listflags_has(listflags, DC_GCL_ADD_SELF) == false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use std::ffi::CStr;
|
||||
use std::ptr;
|
||||
use std::str::FromStr;
|
||||
|
||||
use libc::{free, strcmp, strlen, strncmp};
|
||||
use mmime::clist::*;
|
||||
use mmime::mailimf::*;
|
||||
use mmime::mailimf_types::*;
|
||||
@@ -30,7 +31,6 @@ use crate::keyring::*;
|
||||
use crate::peerstate::*;
|
||||
use crate::pgp::*;
|
||||
use crate::securejoin::handle_degrade_event;
|
||||
use crate::x::*;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct E2eeHelper {
|
||||
|
||||
@@ -19,7 +19,6 @@ use crate::login_param::LoginParam;
|
||||
use crate::message::{self, Message, MessageState};
|
||||
use crate::param::*;
|
||||
use crate::sql;
|
||||
use crate::x::*;
|
||||
|
||||
/// Thread IDs
|
||||
#[derive(Debug, Display, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql)]
|
||||
@@ -140,7 +139,7 @@ impl Job {
|
||||
}
|
||||
|
||||
if let Some(filename) = self.param.get(Param::File) {
|
||||
if let Some(body) = dc_read_file_safe(context, filename) {
|
||||
if let Ok(body) = dc_read_file(context, filename) {
|
||||
if let Some(recipients) = self.param.get(Param::Recipients) {
|
||||
let recipients_list = recipients
|
||||
.split("\x1e")
|
||||
@@ -670,7 +669,7 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: u32) -> libc::c_int {
|
||||
mimefactory.msg.param.set_int(Param::Width, 0);
|
||||
mimefactory.msg.param.set_int(Param::Height, 0);
|
||||
|
||||
if let Some(buf) = dc_read_file_safe(context, pathNfilename) {
|
||||
if let Ok(buf) = dc_read_file(context, pathNfilename) {
|
||||
if let Ok((width, height)) = dc_get_filemeta(&buf) {
|
||||
mimefactory.msg.param.set_int(Param::Width, width as i32);
|
||||
mimefactory.msg.param.set_int(Param::Height, height as i32);
|
||||
@@ -1047,7 +1046,7 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &MimeFactory) ->
|
||||
success = 1;
|
||||
}
|
||||
unsafe {
|
||||
free(recipients.cast());
|
||||
libc::free(recipients.cast());
|
||||
}
|
||||
success
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ pub mod qr;
|
||||
mod smtp;
|
||||
pub mod sql;
|
||||
mod stock;
|
||||
pub mod x;
|
||||
|
||||
pub mod dc_array;
|
||||
mod dc_dehtml;
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::path::{Path, PathBuf};
|
||||
use std::ptr;
|
||||
|
||||
use deltachat_derive::{FromSql, ToSql};
|
||||
use libc::{free, strcmp};
|
||||
use phf::phf_map;
|
||||
|
||||
use crate::chat::{self, Chat};
|
||||
@@ -18,7 +19,6 @@ use crate::param::*;
|
||||
use crate::pgp::*;
|
||||
use crate::sql;
|
||||
use crate::stock::StockMessage;
|
||||
use crate::x::*;
|
||||
|
||||
/// In practice, the user additionally cuts the string himself pixel-accurate.
|
||||
const SUMMARY_CHARACTERS: usize = 160;
|
||||
@@ -351,7 +351,7 @@ impl Message {
|
||||
}
|
||||
|
||||
if let Some(filename) = self.get_file(context) {
|
||||
if let Some(mut buf) = dc_read_file_safe(context, filename) {
|
||||
if let Ok(mut buf) = dc_read_file(context, filename) {
|
||||
unsafe {
|
||||
// just a pointer inside buf, MUST NOT be free()'d
|
||||
let mut buf_headerline = ptr::null();
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::convert::TryInto;
|
||||
use std::io::Cursor;
|
||||
use std::ptr;
|
||||
|
||||
use libc::{strchr, strlen, strncmp, strspn, strstr};
|
||||
use pgp::composed::{
|
||||
Deserializable, KeyType as PgpKeyType, Message, SecretKeyParamsBuilder, SignedPublicKey,
|
||||
SignedSecretKey, SubkeyParamsBuilder,
|
||||
@@ -15,7 +16,6 @@ use crate::dc_tools::*;
|
||||
use crate::error::Error;
|
||||
use crate::key::*;
|
||||
use crate::keyring::*;
|
||||
use crate::x::*;
|
||||
|
||||
pub unsafe fn dc_split_armored_data(
|
||||
buf: *mut libc::c_char,
|
||||
|
||||
@@ -7,7 +7,6 @@ use crate::contact::*;
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::*;
|
||||
use crate::events::Event;
|
||||
use libc::free;
|
||||
|
||||
/// Stock strings
|
||||
///
|
||||
@@ -133,7 +132,7 @@ impl Context {
|
||||
Cow::Borrowed(id.fallback())
|
||||
} else {
|
||||
let ret = to_string(ptr);
|
||||
unsafe { free(ptr as *mut libc::c_void) };
|
||||
unsafe { libc::free(ptr as *mut libc::c_void) };
|
||||
Cow::Owned(ret)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,19 +15,21 @@ if __name__ == "__main__":
|
||||
unsafe = s.count("unsafe")
|
||||
free = s.count("free(")
|
||||
gotoblocks = s.count("ok_to_continue") + s.count('OK_TO_CONTINUE')
|
||||
filestats.append((fn, unsafe, free, gotoblocks))
|
||||
chars = s.count("c_char") + s.count("CStr")
|
||||
filestats.append((fn, unsafe, free, gotoblocks, chars))
|
||||
|
||||
sum_unsafe, sum_free, sum_gotoblocks = 0, 0, 0
|
||||
sum_unsafe, sum_free, sum_gotoblocks, sum_chars = 0, 0, 0, 0
|
||||
|
||||
for fn, unsafe, free, gotoblocks in reversed(sorted(filestats, key=lambda x: sum(x[1:]))):
|
||||
print("{0: <30} unsafe: {1: >3} free: {2: >3} ok_to_continue: {3: >3}".format(str(fn), unsafe, free, gotoblocks))
|
||||
for fn, unsafe, free, gotoblocks, chars in reversed(sorted(filestats, key=lambda x: sum(x[1:]))):
|
||||
print("{0: <25} unsafe: {1: >3} free: {2: >3} ok_to_cont: {3: >3} chars: {4: >3}".format(str(fn), unsafe, free, gotoblocks, chars))
|
||||
sum_unsafe += unsafe
|
||||
sum_free += free
|
||||
sum_gotoblocks += gotoblocks
|
||||
sum_chars += chars
|
||||
|
||||
|
||||
print()
|
||||
print("total unsafe:", sum_unsafe)
|
||||
print("total free:", sum_free)
|
||||
print("total ok_to_continue:", sum_gotoblocks)
|
||||
|
||||
print("total c_chars:", sum_chars)
|
||||
|
||||
67
src/x.rs
67
src/x.rs
@@ -1,67 +0,0 @@
|
||||
pub use libc::{
|
||||
calloc, exit, free, malloc, memcmp, memcpy, memmove, memset, realloc, strcat, strchr, strcmp,
|
||||
strcpy, strcspn, strlen, strncmp, strncpy, strrchr, strspn, strstr, strtol, system,
|
||||
};
|
||||
|
||||
pub unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char {
|
||||
if s.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
let slen = strlen(s);
|
||||
let result = malloc(slen + 1);
|
||||
if result.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
memcpy(result, s as *const _, slen + 1);
|
||||
result as *mut _
|
||||
}
|
||||
|
||||
pub fn strndup(s: *const libc::c_char, n: libc::c_ulong) -> *mut libc::c_char {
|
||||
if s.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
let end = std::cmp::min(n as usize, unsafe { strlen(s) });
|
||||
unsafe {
|
||||
let result = malloc(end + 1);
|
||||
memcpy(result, s as *const _, end);
|
||||
std::ptr::write_bytes(result.offset(end as isize), b'\x00', 1);
|
||||
|
||||
result as *mut _
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char) -> libc::c_int {
|
||||
let s1 = std::ffi::CStr::from_ptr(s1)
|
||||
.to_string_lossy()
|
||||
.to_lowercase();
|
||||
let s2 = std::ffi::CStr::from_ptr(s2)
|
||||
.to_string_lossy()
|
||||
.to_lowercase();
|
||||
if s1 == s2 {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::dc_tools::to_string;
|
||||
|
||||
#[test]
|
||||
fn test_strndup() {
|
||||
unsafe {
|
||||
let res = strndup(b"helloworld\x00" as *const u8 as *const libc::c_char, 4);
|
||||
assert_eq!(
|
||||
to_string(res),
|
||||
to_string(b"hell\x00" as *const u8 as *const libc::c_char)
|
||||
);
|
||||
assert_eq!(strlen(res), 4);
|
||||
free(res as *mut _);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
//! Stress some functions for testing; if used as a lib, this file is obsolete.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use std::ptr;
|
||||
|
||||
use tempfile::{tempdir, TempDir};
|
||||
|
||||
use deltachat::chat::{self, Chat};
|
||||
use deltachat::config;
|
||||
use deltachat::contact::*;
|
||||
@@ -15,9 +12,9 @@ use deltachat::dc_tools::*;
|
||||
use deltachat::keyring::*;
|
||||
use deltachat::oauth2::*;
|
||||
use deltachat::pgp::*;
|
||||
use deltachat::x::*;
|
||||
use deltachat::Event;
|
||||
use libc;
|
||||
use libc::{free, strcmp, strdup, strlen, strncmp};
|
||||
use tempfile::{tempdir, TempDir};
|
||||
|
||||
/* some data used for testing
|
||||
******************************************************************************/
|
||||
@@ -30,68 +27,6 @@ static mut S_EM_SETUPFILE: *const libc::c_char =
|
||||
as *const u8 as *const libc::c_char;
|
||||
|
||||
unsafe fn stress_functions(context: &Context) {
|
||||
if dc_file_exist(context, "$BLOBDIR/foobar")
|
||||
|| dc_file_exist(context, "$BLOBDIR/dada")
|
||||
|| dc_file_exist(context, "$BLOBDIR/foobar.dadada")
|
||||
|| dc_file_exist(context, "$BLOBDIR/foobar-folder")
|
||||
{
|
||||
dc_delete_file(context, "$BLOBDIR/foobar");
|
||||
dc_delete_file(context, "$BLOBDIR/dada");
|
||||
dc_delete_file(context, "$BLOBDIR/foobar.dadada");
|
||||
dc_delete_file(context, "$BLOBDIR/foobar-folder");
|
||||
}
|
||||
assert!(dc_write_file(context, "$BLOBDIR/foobar", b"content"));
|
||||
assert!(dc_file_exist(context, "$BLOBDIR/foobar",));
|
||||
assert!(!dc_file_exist(context, "$BLOBDIR/foobarx"));
|
||||
assert_eq!(dc_get_filebytes(context, "$BLOBDIR/foobar"), 7);
|
||||
|
||||
let abs_path = context
|
||||
.get_blobdir()
|
||||
.join("foobar")
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
|
||||
assert!(dc_is_blobdir_path(context, &abs_path));
|
||||
assert!(dc_is_blobdir_path(context, "$BLOBDIR/fofo",));
|
||||
assert!(!dc_is_blobdir_path(context, "/BLOBDIR/fofo",));
|
||||
assert!(dc_file_exist(context, &abs_path));
|
||||
|
||||
assert!(dc_copy_file(context, "$BLOBDIR/foobar", "$BLOBDIR/dada",));
|
||||
assert_eq!(dc_get_filebytes(context, "$BLOBDIR/dada",), 7);
|
||||
|
||||
let mut buf: *mut libc::c_void = ptr::null_mut();
|
||||
let mut buf_bytes: libc::size_t = 0;
|
||||
|
||||
assert_eq!(
|
||||
dc_read_file(
|
||||
context,
|
||||
b"$BLOBDIR/dada\x00" as *const u8 as *const libc::c_char,
|
||||
&mut buf,
|
||||
&mut buf_bytes,
|
||||
),
|
||||
1
|
||||
);
|
||||
assert_eq!(buf_bytes, 7);
|
||||
assert_eq!(
|
||||
std::str::from_utf8(std::slice::from_raw_parts(buf as *const u8, buf_bytes)).unwrap(),
|
||||
"content"
|
||||
);
|
||||
|
||||
free(buf as *mut _);
|
||||
assert!(dc_delete_file(context, "$BLOBDIR/foobar"));
|
||||
assert!(dc_delete_file(context, "$BLOBDIR/dada"));
|
||||
assert!(dc_create_folder(context, "$BLOBDIR/foobar-folder"));
|
||||
assert!(dc_file_exist(context, "$BLOBDIR/foobar-folder",));
|
||||
assert!(!dc_delete_file(context, "$BLOBDIR/foobar-folder"));
|
||||
let fn0 = dc_get_fine_path_filename(context, "$BLOBDIR", "foobar.dadada");
|
||||
assert_eq!(fn0, PathBuf::from("$BLOBDIR/foobar.dadada"));
|
||||
|
||||
assert!(dc_write_file(context, &fn0, b"content"));
|
||||
let fn1 = dc_get_fine_path_filename(context, "$BLOBDIR", "foobar.dadada");
|
||||
assert_eq!(fn1, PathBuf::from("$BLOBDIR/foobar-1.dadada"));
|
||||
|
||||
assert!(dc_delete_file(context, &fn0));
|
||||
|
||||
let res = context.get_config(config::Config::SysConfigKeys).unwrap();
|
||||
|
||||
assert!(!res.contains(" probably_never_a_key "));
|
||||
|
||||
Reference in New Issue
Block a user