mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
refactor(tools): no more dc_mprintf
This commit is contained in:
@@ -101,7 +101,6 @@ pub unsafe fn dc_imex_has_backup(
|
||||
}
|
||||
|
||||
pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char {
|
||||
let mut setup_file_name: *mut libc::c_char = ptr::null_mut();
|
||||
let mut msg: Message;
|
||||
if !dc_alloc_ongoing(context) {
|
||||
return std::ptr::null_mut();
|
||||
@@ -115,8 +114,7 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char {
|
||||
.unwrap()
|
||||
.shall_stop_ongoing
|
||||
{
|
||||
if let Ok(setup_file_content) = dc_render_setup_file(context, &setup_code) {
|
||||
let setup_file_content_c = CString::yolo(setup_file_content.as_str());
|
||||
if let Ok(ref setup_file_content) = dc_render_setup_file(context, &setup_code) {
|
||||
/* encrypting may also take a while ... */
|
||||
if !context
|
||||
.running_state
|
||||
@@ -125,23 +123,14 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char {
|
||||
.unwrap()
|
||||
.shall_stop_ongoing
|
||||
{
|
||||
setup_file_name = dc_get_fine_pathNfilename(
|
||||
context,
|
||||
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
|
||||
b"autocrypt-setup-message.html\x00" as *const u8 as *const libc::c_char,
|
||||
);
|
||||
if !(setup_file_name.is_null()
|
||||
|| 0 == dc_write_file(
|
||||
context,
|
||||
setup_file_name,
|
||||
setup_file_content_c.as_ptr() as *const libc::c_void,
|
||||
setup_file_content_c.as_bytes().len(),
|
||||
))
|
||||
{
|
||||
let setup_file_name =
|
||||
dc_get_fine_path_filename(context, "$BLOBDIR", "autocrypt-setup-message.html");
|
||||
if dc_write_file(context, &setup_file_name, setup_file_content.as_bytes()) {
|
||||
if let Ok(chat_id) = chat::create_by_contact_id(context, 1) {
|
||||
msg = dc_msg_new_untyped();
|
||||
msg.type_0 = Viewtype::File;
|
||||
msg.param.set(Param::File, as_str(setup_file_name));
|
||||
msg.param
|
||||
.set(Param::File, setup_file_name.to_string_lossy());
|
||||
|
||||
msg.param
|
||||
.set(Param::MimeType, "application/autocrypt-setup");
|
||||
@@ -182,7 +171,6 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char {
|
||||
}
|
||||
}
|
||||
}
|
||||
free(setup_file_name as *mut libc::c_void);
|
||||
dc_free_ongoing(context);
|
||||
|
||||
setup_code.strdup()
|
||||
@@ -640,7 +628,7 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char
|
||||
}
|
||||
|
||||
let pathNfilename = context.get_blobdir().join(file_name);
|
||||
if dc_write_file_safe(context, &pathNfilename, &file_blob) {
|
||||
if dc_write_file(context, &pathNfilename, &file_blob) {
|
||||
continue;
|
||||
}
|
||||
error!(
|
||||
@@ -687,13 +675,8 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> bool {
|
||||
let res = chrono::NaiveDateTime::from_timestamp(now as i64, 0)
|
||||
.format("delta-chat-%Y-%m-%d.bak")
|
||||
.to_string();
|
||||
let buffer = CString::yolo(res);
|
||||
let dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer.as_ptr());
|
||||
if dest_pathNfilename.is_null() {
|
||||
error!(context, "Cannot get backup file name.",);
|
||||
|
||||
return success;
|
||||
}
|
||||
let dest_path_filename = dc_get_fine_path_filename(context, as_path(dir), res);
|
||||
|
||||
sql::housekeeping(context);
|
||||
|
||||
@@ -704,15 +687,15 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> bool {
|
||||
context,
|
||||
"Backup \"{}\" to \"{}\".",
|
||||
context.get_dbfile().display(),
|
||||
as_str(dest_pathNfilename),
|
||||
dest_path_filename.display(),
|
||||
);
|
||||
if dc_copy_file(context, context.get_dbfile(), as_path(dest_pathNfilename)) {
|
||||
if dc_copy_file(context, context.get_dbfile(), &dest_path_filename) {
|
||||
context.sql.open(&context, &context.get_dbfile(), 0);
|
||||
closed = false;
|
||||
/* add all files as blobs to the database copy (this does not require the source to be locked, neigher the destination as it is used only here) */
|
||||
/*for logging only*/
|
||||
let sql = Sql::new();
|
||||
if sql.open(context, as_path(dest_pathNfilename), 0) {
|
||||
if sql.open(context, &dest_path_filename, 0) {
|
||||
if !sql.table_exists("backup_blobs") {
|
||||
if sql::execute(
|
||||
context,
|
||||
@@ -821,9 +804,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> bool {
|
||||
.set_config_int(context, "backup_time", now as i32)
|
||||
.is_ok()
|
||||
{
|
||||
context.call_cb(Event::ImexFileWritten(
|
||||
as_path(dest_pathNfilename).to_path_buf(),
|
||||
));
|
||||
context.call_cb(Event::ImexFileWritten(&dest_path_filename));
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
@@ -841,9 +822,8 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> bool {
|
||||
context.sql.open(&context, &context.get_dbfile(), 0);
|
||||
}
|
||||
if 0 != delete_dest_file {
|
||||
dc_delete_file(context, as_path(dest_pathNfilename));
|
||||
dc_delete_file(context, &dest_path_filename);
|
||||
}
|
||||
free(dest_pathNfilename as *mut libc::c_void);
|
||||
|
||||
success
|
||||
}
|
||||
|
||||
@@ -1301,44 +1301,30 @@ unsafe fn do_add_single_file_part(
|
||||
decoded_data_bytes: libc::size_t,
|
||||
desired_filename: *const libc::c_char,
|
||||
) {
|
||||
let pathNfilename: *mut libc::c_char;
|
||||
/* create a free file name to use */
|
||||
pathNfilename = dc_get_fine_pathNfilename(
|
||||
(*parser).context,
|
||||
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
|
||||
desired_filename,
|
||||
);
|
||||
if !pathNfilename.is_null() {
|
||||
/* copy data to file */
|
||||
if !(dc_write_file(
|
||||
(*parser).context,
|
||||
pathNfilename,
|
||||
decoded_data as *const libc::c_void,
|
||||
decoded_data_bytes,
|
||||
) == 0i32)
|
||||
{
|
||||
let mut part = dc_mimepart_new();
|
||||
part.type_0 = msg_type;
|
||||
part.int_mimetype = mime_type;
|
||||
part.bytes = decoded_data_bytes as libc::c_int;
|
||||
part.param.set(Param::File, as_str(pathNfilename));
|
||||
part.param.set(Param::MimeType, raw_mime);
|
||||
if mime_type == 80 {
|
||||
assert!(!decoded_data.is_null(), "invalid image data");
|
||||
let data = std::slice::from_raw_parts(
|
||||
decoded_data as *const u8,
|
||||
decoded_data_bytes as usize,
|
||||
);
|
||||
let path_filename =
|
||||
dc_get_fine_path_filename((*parser).context, "$BLOBDIR", as_str(desired_filename));
|
||||
let bytes = std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes);
|
||||
|
||||
if let Ok((width, height)) = dc_get_filemeta(data) {
|
||||
part.param.set_int(Param::Width, width as i32);
|
||||
part.param.set_int(Param::Height, height as i32);
|
||||
}
|
||||
/* copy data to file */
|
||||
if dc_write_file((*parser).context, &path_filename, bytes) {
|
||||
let mut part = dc_mimepart_new();
|
||||
part.type_0 = msg_type;
|
||||
part.int_mimetype = mime_type;
|
||||
part.bytes = decoded_data_bytes as libc::c_int;
|
||||
part.param.set(Param::File, path_filename.to_string_lossy());
|
||||
part.param.set(Param::MimeType, raw_mime);
|
||||
if mime_type == 80 {
|
||||
assert!(!decoded_data.is_null(), "invalid image data");
|
||||
let data =
|
||||
std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes as usize);
|
||||
|
||||
if let Ok((width, height)) = dc_get_filemeta(data) {
|
||||
part.param.set_int(Param::Width, width as i32);
|
||||
part.param.set_int(Param::Height, height as i32);
|
||||
}
|
||||
do_add_single_part(parser, part);
|
||||
}
|
||||
do_add_single_part(parser, part);
|
||||
}
|
||||
free(pathNfilename as *mut libc::c_void);
|
||||
}
|
||||
|
||||
unsafe fn do_add_single_part(parser: &mut dc_mimeparser_t, mut part: dc_mimepart_t) {
|
||||
|
||||
280
src/dc_tools.rs
280
src/dc_tools.rs
@@ -1,12 +1,14 @@
|
||||
//! Some tools and enhancements to the used libraries, there should be
|
||||
//! no references to Context and other "larger" entities here.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::path::Path;
|
||||
use std::ffi::{CStr, CString, OsString};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::time::SystemTime;
|
||||
use std::{fmt, fs, ptr};
|
||||
|
||||
use chrono::{Local, TimeZone};
|
||||
use itertools::max;
|
||||
use libc::uintptr_t;
|
||||
use mmime::clist::*;
|
||||
use mmime::mailimf_types::*;
|
||||
@@ -16,10 +18,6 @@ use crate::context::Context;
|
||||
use crate::error::Error;
|
||||
use crate::x::*;
|
||||
|
||||
/* Some tools and enhancements to the used libraries, there should be
|
||||
no references to Context and other "larger" classes here. */
|
||||
/* ** library-private **********************************************************/
|
||||
/* math tools */
|
||||
pub fn dc_exactly_one_bit_set(v: libc::c_int) -> bool {
|
||||
0 != v && 0 == v & (v - 1)
|
||||
}
|
||||
@@ -570,7 +568,7 @@ fn encode_66bits_as_base64(v1: u32, v2: u32, fill: u32) -> String {
|
||||
String::from_utf8(wrapped_writer).unwrap()
|
||||
}
|
||||
|
||||
pub unsafe fn dc_create_incoming_rfc724_mid(
|
||||
pub fn dc_create_incoming_rfc724_mid(
|
||||
message_timestamp: i64,
|
||||
contact_id_from: u32,
|
||||
contact_ids_to: &Vec<u32>,
|
||||
@@ -579,51 +577,36 @@ pub unsafe fn dc_create_incoming_rfc724_mid(
|
||||
return ptr::null_mut();
|
||||
}
|
||||
/* find out the largest receiver ID (we could also take the smallest, but it should be unique) */
|
||||
let largest_id_to = max(contact_ids_to.iter());
|
||||
let largest_id_to = contact_ids_to.iter().max().copied().unwrap_or_default();
|
||||
|
||||
dc_mprintf(
|
||||
b"%lu-%lu-%lu@stub\x00" as *const u8 as *const libc::c_char,
|
||||
message_timestamp as libc::c_ulong,
|
||||
contact_id_from as libc::c_ulong,
|
||||
*largest_id_to.unwrap() as libc::c_ulong,
|
||||
)
|
||||
let result = format!(
|
||||
"{}-{}-{}@stub",
|
||||
message_timestamp, contact_id_from, largest_id_to
|
||||
);
|
||||
|
||||
unsafe { result.strdup() }
|
||||
}
|
||||
|
||||
/// Function generates a Message-ID that can be used for a new outgoing message.
|
||||
/// - 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 as this may give unneeded information to the receiver
|
||||
pub unsafe fn dc_create_outgoing_rfc724_mid(
|
||||
grpid: *const libc::c_char,
|
||||
from_addr: *const libc::c_char,
|
||||
) -> *mut libc::c_char {
|
||||
/* Function generates a Message-ID that can be used for a new outgoing message.
|
||||
- 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 as this may give unneeded information to the receiver */
|
||||
let mut rand1: *mut libc::c_char = ptr::null_mut();
|
||||
let rand2: *mut libc::c_char = dc_create_id().strdup();
|
||||
let ret: *mut libc::c_char;
|
||||
let mut at_hostname: *const libc::c_char = strchr(from_addr, '@' as i32);
|
||||
if at_hostname.is_null() {
|
||||
at_hostname = b"@nohost\x00" as *const u8 as *const libc::c_char
|
||||
}
|
||||
if !grpid.is_null() {
|
||||
ret = dc_mprintf(
|
||||
b"Gr.%s.%s%s\x00" as *const u8 as *const libc::c_char,
|
||||
grpid,
|
||||
rand2,
|
||||
at_hostname,
|
||||
)
|
||||
} else {
|
||||
rand1 = dc_create_id().strdup();
|
||||
ret = dc_mprintf(
|
||||
b"Mr.%s.%s%s\x00" as *const u8 as *const libc::c_char,
|
||||
rand1,
|
||||
rand2,
|
||||
at_hostname,
|
||||
)
|
||||
}
|
||||
free(rand1 as *mut libc::c_void);
|
||||
free(rand2 as *mut libc::c_void);
|
||||
let rand2 = dc_create_id();
|
||||
|
||||
ret
|
||||
let at_hostname = as_opt_str(strchr(from_addr, '@' as i32)).unwrap_or_else(|| "@nohost");
|
||||
|
||||
let ret = if !grpid.is_null() {
|
||||
format!("Gr.{}.{}{}", as_str(grpid), rand2, at_hostname,)
|
||||
} else {
|
||||
let rand1 = dc_create_id();
|
||||
format!("Mr.{}.{}{}", rand1, rand2, at_hostname)
|
||||
};
|
||||
|
||||
ret.strdup()
|
||||
}
|
||||
|
||||
/// Generate globally-unique message-id for a new outgoing message.
|
||||
@@ -696,16 +679,6 @@ pub unsafe fn dc_extract_grpid_from_rfc724_mid_list(list: *const clist) -> *mut
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn dc_ensure_no_slash(pathNfilename: *mut libc::c_char) {
|
||||
let path_len = strlen(pathNfilename);
|
||||
if path_len > 0 && *pathNfilename.add(path_len - 1) as libc::c_int == '/' as i32
|
||||
|| *pathNfilename.add(path_len - 1) as libc::c_int == '\\' as i32
|
||||
{
|
||||
*pathNfilename.add(path_len - 1) = 0 as libc::c_char;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dc_ensure_no_slash_safe(path: &str) -> &str {
|
||||
if path.ends_with('/') || path.ends_with('\\') {
|
||||
return &path[..path.len() - 1];
|
||||
@@ -713,18 +686,12 @@ pub fn dc_ensure_no_slash_safe(path: &str) -> &str {
|
||||
path
|
||||
}
|
||||
|
||||
unsafe fn dc_validate_filename(filename: *mut libc::c_char) {
|
||||
/* function modifies the given buffer and replaces all characters not valid in filenames by a "-" */
|
||||
let mut p1: *mut libc::c_char = filename;
|
||||
while 0 != *p1 {
|
||||
if *p1 as libc::c_int == '/' as i32
|
||||
|| *p1 as libc::c_int == '\\' as i32
|
||||
|| *p1 as libc::c_int == ':' as i32
|
||||
{
|
||||
*p1 = '-' as i32 as libc::c_char
|
||||
}
|
||||
p1 = p1.offset(1isize)
|
||||
}
|
||||
/// Function modifies the given buffer and replaces all characters not valid in filenames by a "-".
|
||||
fn validate_filename(filename: &str) -> String {
|
||||
filename
|
||||
.replace('/', "-")
|
||||
.replace('\\', "-")
|
||||
.replace(':', "-")
|
||||
}
|
||||
|
||||
pub unsafe fn dc_get_filename(path_filename: impl AsRef<str>) -> *mut libc::c_char {
|
||||
@@ -735,42 +702,6 @@ pub unsafe fn dc_get_filename(path_filename: impl AsRef<str>) -> *mut libc::c_ch
|
||||
}
|
||||
}
|
||||
|
||||
// the case of the suffix is preserved
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn dc_split_filename(
|
||||
pathNfilename: *const libc::c_char,
|
||||
ret_basename: *mut *mut libc::c_char,
|
||||
ret_all_suffixes_incl_dot: *mut *mut libc::c_char,
|
||||
) {
|
||||
if pathNfilename.is_null() {
|
||||
return;
|
||||
}
|
||||
/* splits a filename into basename and all suffixes, eg. "/path/foo.tar.gz" is split into "foo.tar" and ".gz",
|
||||
(we use the _last_ dot which allows the usage inside the filename which are very usual;
|
||||
maybe the detection could be more intelligent, however, for the moment, it is just file)
|
||||
- if there is no suffix, the returned suffix string is empty, eg. "/path/foobar" is split into "foobar" and ""
|
||||
- the case of the returned suffix is preserved; this is to allow reconstruction of (similar) names */
|
||||
let basename: *mut libc::c_char = dc_get_filename(as_str(pathNfilename));
|
||||
let suffix: *mut libc::c_char;
|
||||
let p1: *mut libc::c_char = strrchr(basename, '.' as i32);
|
||||
if !p1.is_null() {
|
||||
suffix = dc_strdup(p1);
|
||||
*p1 = 0 as libc::c_char
|
||||
} else {
|
||||
suffix = dc_strdup(ptr::null())
|
||||
}
|
||||
if !ret_basename.is_null() {
|
||||
*ret_basename = basename
|
||||
} else {
|
||||
free(basename as *mut libc::c_void);
|
||||
}
|
||||
if !ret_all_suffixes_incl_dot.is_null() {
|
||||
*ret_all_suffixes_incl_dot = suffix
|
||||
} else {
|
||||
free(suffix as *mut libc::c_void);
|
||||
};
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@@ -876,23 +807,8 @@ pub fn dc_create_folder(context: &Context, path: impl AsRef<std::path::Path>) ->
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe fn dc_write_file(
|
||||
context: &Context,
|
||||
pathNfilename: *const libc::c_char,
|
||||
buf: *const libc::c_void,
|
||||
buf_bytes: libc::size_t,
|
||||
) -> libc::c_int {
|
||||
let bytes = std::slice::from_raw_parts(buf as *const u8, buf_bytes);
|
||||
|
||||
dc_write_file_safe(context, as_str(pathNfilename), bytes) as libc::c_int
|
||||
}
|
||||
|
||||
pub fn dc_write_file_safe<P: AsRef<std::path::Path>>(
|
||||
context: &Context,
|
||||
path: P,
|
||||
buf: &[u8],
|
||||
) -> bool {
|
||||
/// Write a the given content to provied file path.
|
||||
pub 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!(
|
||||
@@ -942,58 +858,48 @@ pub fn dc_read_file_safe<P: AsRef<std::path::Path>>(context: &Context, path: P)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe fn dc_get_fine_pathNfilename(
|
||||
pub fn dc_get_fine_path_filename(
|
||||
context: &Context,
|
||||
pathNfolder: *const libc::c_char,
|
||||
desired_filenameNsuffix__: *const libc::c_char,
|
||||
) -> *mut libc::c_char {
|
||||
let mut ret: *mut libc::c_char = ptr::null_mut();
|
||||
let pathNfolder_wo_slash: *mut libc::c_char;
|
||||
let filenameNsuffix: *mut libc::c_char;
|
||||
let mut basename: *mut libc::c_char = ptr::null_mut();
|
||||
let mut dotNSuffix: *mut libc::c_char = ptr::null_mut();
|
||||
folder: impl AsRef<Path>,
|
||||
desired_filename_suffix: impl AsRef<str>,
|
||||
) -> PathBuf {
|
||||
let now = time();
|
||||
|
||||
pathNfolder_wo_slash = dc_strdup(pathNfolder);
|
||||
dc_ensure_no_slash(pathNfolder_wo_slash);
|
||||
filenameNsuffix = dc_strdup(desired_filenameNsuffix__);
|
||||
dc_validate_filename(filenameNsuffix);
|
||||
dc_split_filename(filenameNsuffix, &mut basename, &mut dotNSuffix);
|
||||
let folder = PathBuf::from(folder.as_ref());
|
||||
let suffix = validate_filename(desired_filename_suffix.as_ref());
|
||||
|
||||
for i in 0..1000i64 {
|
||||
/*no deadlocks, please*/
|
||||
if 0 != i {
|
||||
let idx = if i < 100 { i } else { now + i };
|
||||
ret = dc_mprintf(
|
||||
b"%s/%s-%lu%s\x00" as *const u8 as *const libc::c_char,
|
||||
pathNfolder_wo_slash,
|
||||
basename,
|
||||
idx as libc::c_ulong,
|
||||
dotNSuffix,
|
||||
)
|
||||
let file_name = PathBuf::from(suffix);
|
||||
let extension = file_name.extension().map(|c| c.clone());
|
||||
|
||||
for i in 0..100_000 {
|
||||
let ret = if i == 0 {
|
||||
let mut folder = folder.clone();
|
||||
folder.push(&file_name);
|
||||
folder
|
||||
} else {
|
||||
ret = dc_mprintf(
|
||||
b"%s/%s%s\x00" as *const u8 as *const libc::c_char,
|
||||
pathNfolder_wo_slash,
|
||||
basename,
|
||||
dotNSuffix,
|
||||
)
|
||||
let idx = if i < 100 { i } else { now + i };
|
||||
let file_name = if let Some(stem) = file_name.file_stem() {
|
||||
let mut stem = stem.to_os_string();
|
||||
stem.push(format!("-{}", idx));
|
||||
stem
|
||||
} else {
|
||||
OsString::from(idx.to_string())
|
||||
};
|
||||
let mut folder = folder.clone();
|
||||
folder.push(file_name);
|
||||
if let Some(ext) = extension {
|
||||
folder.set_extension(&ext);
|
||||
}
|
||||
folder
|
||||
};
|
||||
|
||||
if !dc_file_exist(context, &ret) {
|
||||
// fine filename found
|
||||
return ret;
|
||||
}
|
||||
if !dc_file_exist(context, as_path(ret)) {
|
||||
/* fine filename found */
|
||||
break;
|
||||
}
|
||||
free(ret as *mut libc::c_void);
|
||||
ret = ptr::null_mut();
|
||||
}
|
||||
|
||||
free(filenameNsuffix as *mut libc::c_void);
|
||||
free(basename as *mut libc::c_void);
|
||||
free(dotNSuffix as *mut libc::c_void);
|
||||
free(pathNfolder_wo_slash as *mut libc::c_void);
|
||||
|
||||
ret
|
||||
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 {
|
||||
@@ -1017,38 +923,18 @@ fn dc_make_rel_path(context: &Context, path: &mut String) {
|
||||
}
|
||||
|
||||
pub fn dc_make_rel_and_copy(context: &Context, path: &mut String) -> bool {
|
||||
let mut success = false;
|
||||
let mut filename = ptr::null_mut();
|
||||
let mut blobdir_path = ptr::null_mut();
|
||||
if dc_is_blobdir_path(context, &path) {
|
||||
dc_make_rel_path(context, path);
|
||||
success = true;
|
||||
} else {
|
||||
filename = unsafe { dc_get_filename(&path) };
|
||||
if !(filename.is_null()
|
||||
|| {
|
||||
blobdir_path = unsafe {
|
||||
dc_get_fine_pathNfilename(
|
||||
context,
|
||||
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
|
||||
filename,
|
||||
)
|
||||
};
|
||||
blobdir_path.is_null()
|
||||
}
|
||||
|| !dc_copy_file(context, &path, as_path(blobdir_path)))
|
||||
{
|
||||
*path = to_string(blobdir_path);
|
||||
blobdir_path = ptr::null_mut();
|
||||
dc_make_rel_path(context, path);
|
||||
success = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
unsafe {
|
||||
free(blobdir_path.cast());
|
||||
free(filename.cast());
|
||||
let blobdir_path = dc_get_fine_path_filename(context, "$BLOBDIR", &path);
|
||||
if dc_copy_file(context, &path, &blobdir_path) {
|
||||
*path = blobdir_path.to_string_lossy().to_string();
|
||||
dc_make_rel_path(context, path);
|
||||
return true;
|
||||
}
|
||||
success
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Error type for the [OsStrExt] trait
|
||||
@@ -1923,4 +1809,14 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dc_create_incoming_rfc724_mid() {
|
||||
let res = dc_create_incoming_rfc724_mid(123, 45, &vec![6, 7]);
|
||||
assert_eq!(as_str(res), "123-45-7@stub");
|
||||
|
||||
unsafe {
|
||||
free(res.cast());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
34
src/job.rs
34
src/job.rs
@@ -998,38 +998,23 @@ fn send_mdn(context: &Context, msg_id: u32) {
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn add_smtp_job(context: &Context, action: Action, mimefactory: &dc_mimefactory_t) -> libc::c_int {
|
||||
let pathNfilename: *mut libc::c_char;
|
||||
let mut success: libc::c_int = 0i32;
|
||||
let mut recipients: *mut libc::c_char = ptr::null_mut();
|
||||
let mut param = Params::new();
|
||||
pathNfilename = unsafe {
|
||||
dc_get_fine_pathNfilename(
|
||||
context,
|
||||
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
|
||||
mimefactory.rfc724_mid,
|
||||
let path_filename =
|
||||
dc_get_fine_path_filename(context, "$BLOBDIR", as_str(mimefactory.rfc724_mid));
|
||||
let bytes = unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
(*mimefactory.out).str_0 as *const u8,
|
||||
(*mimefactory.out).len,
|
||||
)
|
||||
};
|
||||
if pathNfilename.is_null() {
|
||||
error!(
|
||||
context,
|
||||
"Could not find free file name for message with ID <{}>.",
|
||||
to_string(mimefactory.rfc724_mid),
|
||||
);
|
||||
} else if 0
|
||||
== unsafe {
|
||||
dc_write_file(
|
||||
context,
|
||||
pathNfilename,
|
||||
(*mimefactory.out).str_0 as *const libc::c_void,
|
||||
(*mimefactory.out).len,
|
||||
)
|
||||
}
|
||||
{
|
||||
if !dc_write_file(context, &path_filename, bytes) {
|
||||
error!(
|
||||
context,
|
||||
"Could not write message <{}> to \"{}\".",
|
||||
to_string(mimefactory.rfc724_mid),
|
||||
as_str(pathNfilename),
|
||||
path_filename.display(),
|
||||
);
|
||||
} else {
|
||||
recipients = unsafe {
|
||||
@@ -1038,7 +1023,7 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &dc_mimefactory_
|
||||
b"\x1e\x00" as *const u8 as *const libc::c_char,
|
||||
)
|
||||
};
|
||||
param.set(Param::File, as_str(pathNfilename));
|
||||
param.set(Param::File, path_filename.to_string_lossy());
|
||||
param.set(Param::Recipients, as_str(recipients));
|
||||
job_add(
|
||||
context,
|
||||
@@ -1057,7 +1042,6 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &dc_mimefactory_
|
||||
}
|
||||
unsafe {
|
||||
free(recipients.cast());
|
||||
free(pathNfilename.cast());
|
||||
}
|
||||
success
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ impl Key {
|
||||
pub fn write_asc_to_file(&self, file: impl AsRef<Path>, context: &Context) -> bool {
|
||||
let file_content = self.to_asc(None).into_bytes();
|
||||
|
||||
if dc_write_file_safe(context, &file, &file_content) {
|
||||
if dc_write_file(context, &file, &file_content) {
|
||||
return true;
|
||||
} else {
|
||||
error!(context, "Cannot write key to {}", file.as_ref().display());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! 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};
|
||||
@@ -39,15 +40,10 @@ unsafe fn stress_functions(context: &Context) {
|
||||
dc_delete_file(context, "$BLOBDIR/foobar.dadada");
|
||||
dc_delete_file(context, "$BLOBDIR/foobar-folder");
|
||||
}
|
||||
dc_write_file(
|
||||
context,
|
||||
b"$BLOBDIR/foobar\x00" as *const u8 as *const libc::c_char,
|
||||
b"content\x00" as *const u8 as *const libc::c_char as *const libc::c_void,
|
||||
7,
|
||||
);
|
||||
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);
|
||||
assert_eq!(dc_get_filebytes(context, "$BLOBDIR/foobar"), 7);
|
||||
|
||||
let abs_path = context
|
||||
.get_blobdir()
|
||||
@@ -87,41 +83,14 @@ unsafe fn stress_functions(context: &Context) {
|
||||
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: *mut libc::c_char = dc_get_fine_pathNfilename(
|
||||
context,
|
||||
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
|
||||
b"foobar.dadada\x00" as *const u8 as *const libc::c_char,
|
||||
);
|
||||
assert!(!fn0.is_null());
|
||||
assert_eq!(
|
||||
strcmp(
|
||||
fn0,
|
||||
b"$BLOBDIR/foobar.dadada\x00" as *const u8 as *const libc::c_char,
|
||||
),
|
||||
0
|
||||
);
|
||||
dc_write_file(
|
||||
context,
|
||||
fn0,
|
||||
b"content\x00" as *const u8 as *const libc::c_char as *const libc::c_void,
|
||||
7,
|
||||
);
|
||||
let fn1: *mut libc::c_char = dc_get_fine_pathNfilename(
|
||||
context,
|
||||
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
|
||||
b"foobar.dadada\x00" as *const u8 as *const libc::c_char,
|
||||
);
|
||||
assert!(!fn1.is_null());
|
||||
assert_eq!(
|
||||
strcmp(
|
||||
fn1,
|
||||
b"$BLOBDIR/foobar-1.dadada\x00" as *const u8 as *const libc::c_char,
|
||||
),
|
||||
0
|
||||
);
|
||||
assert!(dc_delete_file(context, as_path(fn0)));
|
||||
free(fn0 as *mut libc::c_void);
|
||||
free(fn1 as *mut libc::c_void);
|
||||
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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user