refactor(tools): no more dc_mprintf

This commit is contained in:
dignifiedquire
2019-09-15 21:04:50 +02:00
parent 0bf3d20e07
commit 84bf1ec6e7
6 changed files with 142 additions and 327 deletions

View File

@@ -101,7 +101,6 @@ pub unsafe fn dc_imex_has_backup(
} }
pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char { 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; let mut msg: Message;
if !dc_alloc_ongoing(context) { if !dc_alloc_ongoing(context) {
return std::ptr::null_mut(); return std::ptr::null_mut();
@@ -115,8 +114,7 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char {
.unwrap() .unwrap()
.shall_stop_ongoing .shall_stop_ongoing
{ {
if let Ok(setup_file_content) = dc_render_setup_file(context, &setup_code) { if let Ok(ref setup_file_content) = dc_render_setup_file(context, &setup_code) {
let setup_file_content_c = CString::yolo(setup_file_content.as_str());
/* encrypting may also take a while ... */ /* encrypting may also take a while ... */
if !context if !context
.running_state .running_state
@@ -125,23 +123,14 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char {
.unwrap() .unwrap()
.shall_stop_ongoing .shall_stop_ongoing
{ {
setup_file_name = dc_get_fine_pathNfilename( let setup_file_name =
context, dc_get_fine_path_filename(context, "$BLOBDIR", "autocrypt-setup-message.html");
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char, if dc_write_file(context, &setup_file_name, setup_file_content.as_bytes()) {
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(),
))
{
if let Ok(chat_id) = chat::create_by_contact_id(context, 1) { if let Ok(chat_id) = chat::create_by_contact_id(context, 1) {
msg = dc_msg_new_untyped(); msg = dc_msg_new_untyped();
msg.type_0 = Viewtype::File; 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 msg.param
.set(Param::MimeType, "application/autocrypt-setup"); .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); dc_free_ongoing(context);
setup_code.strdup() 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); 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; continue;
} }
error!( 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) let res = chrono::NaiveDateTime::from_timestamp(now as i64, 0)
.format("delta-chat-%Y-%m-%d.bak") .format("delta-chat-%Y-%m-%d.bak")
.to_string(); .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); sql::housekeeping(context);
@@ -704,15 +687,15 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> bool {
context, context,
"Backup \"{}\" to \"{}\".", "Backup \"{}\" to \"{}\".",
context.get_dbfile().display(), 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); context.sql.open(&context, &context.get_dbfile(), 0);
closed = false; 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) */ /* 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*/ /*for logging only*/
let sql = Sql::new(); 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.table_exists("backup_blobs") {
if sql::execute( if sql::execute(
context, 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) .set_config_int(context, "backup_time", now as i32)
.is_ok() .is_ok()
{ {
context.call_cb(Event::ImexFileWritten( context.call_cb(Event::ImexFileWritten(&dest_path_filename));
as_path(dest_pathNfilename).to_path_buf(),
));
success = true; 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); context.sql.open(&context, &context.get_dbfile(), 0);
} }
if 0 != delete_dest_file { 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 success
} }

View File

@@ -1301,34 +1301,22 @@ unsafe fn do_add_single_file_part(
decoded_data_bytes: libc::size_t, decoded_data_bytes: libc::size_t,
desired_filename: *const libc::c_char, desired_filename: *const libc::c_char,
) { ) {
let pathNfilename: *mut libc::c_char; let path_filename =
/* create a free file name to use */ dc_get_fine_path_filename((*parser).context, "$BLOBDIR", as_str(desired_filename));
pathNfilename = dc_get_fine_pathNfilename( let bytes = std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes);
(*parser).context,
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
desired_filename,
);
if !pathNfilename.is_null() {
/* copy data to file */ /* copy data to file */
if !(dc_write_file( if dc_write_file((*parser).context, &path_filename, bytes) {
(*parser).context,
pathNfilename,
decoded_data as *const libc::c_void,
decoded_data_bytes,
) == 0i32)
{
let mut part = dc_mimepart_new(); let mut part = dc_mimepart_new();
part.type_0 = msg_type; part.type_0 = msg_type;
part.int_mimetype = mime_type; part.int_mimetype = mime_type;
part.bytes = decoded_data_bytes as libc::c_int; part.bytes = decoded_data_bytes as libc::c_int;
part.param.set(Param::File, as_str(pathNfilename)); part.param.set(Param::File, path_filename.to_string_lossy());
part.param.set(Param::MimeType, raw_mime); part.param.set(Param::MimeType, raw_mime);
if mime_type == 80 { if mime_type == 80 {
assert!(!decoded_data.is_null(), "invalid image data"); assert!(!decoded_data.is_null(), "invalid image data");
let data = std::slice::from_raw_parts( let data =
decoded_data as *const u8, std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes as usize);
decoded_data_bytes as usize,
);
if let Ok((width, height)) = dc_get_filemeta(data) { if let Ok((width, height)) = dc_get_filemeta(data) {
part.param.set_int(Param::Width, width as i32); part.param.set_int(Param::Width, width as i32);
@@ -1338,8 +1326,6 @@ unsafe fn do_add_single_file_part(
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) { unsafe fn do_add_single_part(parser: &mut dc_mimeparser_t, mut part: dc_mimepart_t) {
if (*parser).e2ee_helper.encrypted && (*parser).e2ee_helper.signatures.len() > 0 { if (*parser).e2ee_helper.encrypted && (*parser).e2ee_helper.signatures.len() > 0 {

View File

@@ -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::borrow::Cow;
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString, OsString};
use std::path::Path; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
use std::time::SystemTime; use std::time::SystemTime;
use std::{fmt, fs, ptr}; use std::{fmt, fs, ptr};
use chrono::{Local, TimeZone}; use chrono::{Local, TimeZone};
use itertools::max;
use libc::uintptr_t; use libc::uintptr_t;
use mmime::clist::*; use mmime::clist::*;
use mmime::mailimf_types::*; use mmime::mailimf_types::*;
@@ -16,10 +18,6 @@ use crate::context::Context;
use crate::error::Error; use crate::error::Error;
use crate::x::*; 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 { pub fn dc_exactly_one_bit_set(v: libc::c_int) -> bool {
0 != v && 0 == v & (v - 1) 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() String::from_utf8(wrapped_writer).unwrap()
} }
pub unsafe fn dc_create_incoming_rfc724_mid( pub fn dc_create_incoming_rfc724_mid(
message_timestamp: i64, message_timestamp: i64,
contact_id_from: u32, contact_id_from: u32,
contact_ids_to: &Vec<u32>, contact_ids_to: &Vec<u32>,
@@ -579,51 +577,36 @@ pub unsafe fn dc_create_incoming_rfc724_mid(
return ptr::null_mut(); return ptr::null_mut();
} }
/* find out the largest receiver ID (we could also take the smallest, but it should be unique) */ /* 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( let result = format!(
b"%lu-%lu-%lu@stub\x00" as *const u8 as *const libc::c_char, "{}-{}-{}@stub",
message_timestamp as libc::c_ulong, message_timestamp, contact_id_from, largest_id_to
contact_id_from as libc::c_ulong, );
*largest_id_to.unwrap() as libc::c_ulong,
) 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( pub unsafe fn dc_create_outgoing_rfc724_mid(
grpid: *const libc::c_char, grpid: *const libc::c_char,
from_addr: *const libc::c_char, from_addr: *const libc::c_char,
) -> *mut libc::c_char { ) -> *mut libc::c_char {
/* Function generates a Message-ID that can be used for a new outgoing message. let rand2 = dc_create_id();
- 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);
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. /// 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() 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 { pub fn dc_ensure_no_slash_safe(path: &str) -> &str {
if path.ends_with('/') || path.ends_with('\\') { if path.ends_with('/') || path.ends_with('\\') {
return &path[..path.len() - 1]; return &path[..path.len() - 1];
@@ -713,18 +686,12 @@ pub fn dc_ensure_no_slash_safe(path: &str) -> &str {
path 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 "-".
/* function modifies the given buffer and replaces all characters not valid in filenames by a "-" */ fn validate_filename(filename: &str) -> String {
let mut p1: *mut libc::c_char = filename; filename
while 0 != *p1 { .replace('/', "-")
if *p1 as libc::c_int == '/' as i32 .replace('\\', "-")
|| *p1 as libc::c_int == '\\' as i32 .replace(':', "-")
|| *p1 as libc::c_int == ':' as i32
{
*p1 = '-' as i32 as libc::c_char
}
p1 = p1.offset(1isize)
}
} }
pub unsafe fn dc_get_filename(path_filename: impl AsRef<str>) -> *mut libc::c_char { 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 // the returned suffix is lower-case
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub unsafe fn dc_get_filesuffix_lc(path_filename: impl AsRef<str>) -> *mut libc::c_char { 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)] /// Write a the given content to provied file path.
pub unsafe fn dc_write_file( pub fn dc_write_file(context: &Context, path: impl AsRef<Path>, buf: &[u8]) -> bool {
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 {
let path_abs = dc_get_abs_path(context, &path); let path_abs = dc_get_abs_path(context, &path);
if let Err(_err) = fs::write(&path_abs, buf) { if let Err(_err) = fs::write(&path_abs, buf) {
warn!( 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 fn dc_get_fine_path_filename(
pub unsafe fn dc_get_fine_pathNfilename(
context: &Context, context: &Context,
pathNfolder: *const libc::c_char, folder: impl AsRef<Path>,
desired_filenameNsuffix__: *const libc::c_char, desired_filename_suffix: impl AsRef<str>,
) -> *mut libc::c_char { ) -> PathBuf {
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();
let now = time(); let now = time();
pathNfolder_wo_slash = dc_strdup(pathNfolder); let folder = PathBuf::from(folder.as_ref());
dc_ensure_no_slash(pathNfolder_wo_slash); let suffix = validate_filename(desired_filename_suffix.as_ref());
filenameNsuffix = dc_strdup(desired_filenameNsuffix__);
dc_validate_filename(filenameNsuffix);
dc_split_filename(filenameNsuffix, &mut basename, &mut dotNSuffix);
for i in 0..1000i64 { let file_name = PathBuf::from(suffix);
/*no deadlocks, please*/ let extension = file_name.extension().map(|c| c.clone());
if 0 != i {
let idx = if i < 100 { i } else { now + i }; for i in 0..100_000 {
ret = dc_mprintf( let ret = if i == 0 {
b"%s/%s-%lu%s\x00" as *const u8 as *const libc::c_char, let mut folder = folder.clone();
pathNfolder_wo_slash, folder.push(&file_name);
basename, folder
idx as libc::c_ulong,
dotNSuffix,
)
} else { } else {
ret = dc_mprintf( let idx = if i < 100 { i } else { now + i };
b"%s/%s%s\x00" as *const u8 as *const libc::c_char, let file_name = if let Some(stem) = file_name.file_stem() {
pathNfolder_wo_slash, let mut stem = stem.to_os_string();
basename, stem.push(format!("-{}", idx));
dotNSuffix, 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);
} }
if !dc_file_exist(context, as_path(ret)) { folder
/* fine filename found */ };
break;
if !dc_file_exist(context, &ret) {
// fine filename found
return ret;
} }
free(ret as *mut libc::c_void);
ret = ptr::null_mut();
} }
free(filenameNsuffix as *mut libc::c_void); panic!("Something is really wrong, you need to clean up your disk");
free(basename as *mut libc::c_void);
free(dotNSuffix as *mut libc::c_void);
free(pathNfolder_wo_slash as *mut libc::c_void);
ret
} }
pub fn dc_is_blobdir_path(context: &Context, path: impl AsRef<str>) -> bool { 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 { 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) { if dc_is_blobdir_path(context, &path) {
dc_make_rel_path(context, path); dc_make_rel_path(context, path);
success = true; return 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))) let blobdir_path = dc_get_fine_path_filename(context, "$BLOBDIR", &path);
{ if dc_copy_file(context, &path, &blobdir_path) {
*path = to_string(blobdir_path); *path = blobdir_path.to_string_lossy().to_string();
blobdir_path = ptr::null_mut();
dc_make_rel_path(context, path); dc_make_rel_path(context, path);
success = true; return true;
} }
}
unsafe { false
free(blobdir_path.cast());
free(filename.cast());
}
success
} }
/// Error type for the [OsStrExt] trait /// 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());
}
}
} }

View File

@@ -998,38 +998,23 @@ fn send_mdn(context: &Context, msg_id: u32) {
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn add_smtp_job(context: &Context, action: Action, mimefactory: &dc_mimefactory_t) -> libc::c_int { 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 success: libc::c_int = 0i32;
let mut recipients: *mut libc::c_char = ptr::null_mut(); let mut recipients: *mut libc::c_char = ptr::null_mut();
let mut param = Params::new(); let mut param = Params::new();
pathNfilename = unsafe { let path_filename =
dc_get_fine_pathNfilename( dc_get_fine_path_filename(context, "$BLOBDIR", as_str(mimefactory.rfc724_mid));
context, let bytes = unsafe {
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char, std::slice::from_raw_parts(
mimefactory.rfc724_mid, (*mimefactory.out).str_0 as *const u8,
)
};
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, (*mimefactory.out).len,
) )
} };
{ if !dc_write_file(context, &path_filename, bytes) {
error!( error!(
context, context,
"Could not write message <{}> to \"{}\".", "Could not write message <{}> to \"{}\".",
to_string(mimefactory.rfc724_mid), to_string(mimefactory.rfc724_mid),
as_str(pathNfilename), path_filename.display(),
); );
} else { } else {
recipients = unsafe { 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, 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)); param.set(Param::Recipients, as_str(recipients));
job_add( job_add(
context, context,
@@ -1057,7 +1042,6 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &dc_mimefactory_
} }
unsafe { unsafe {
free(recipients.cast()); free(recipients.cast());
free(pathNfilename.cast());
} }
success success
} }

View File

@@ -218,7 +218,7 @@ impl Key {
pub fn write_asc_to_file(&self, file: impl AsRef<Path>, context: &Context) -> bool { pub fn write_asc_to_file(&self, file: impl AsRef<Path>, context: &Context) -> bool {
let file_content = self.to_asc(None).into_bytes(); 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; return true;
} else { } else {
error!(context, "Cannot write key to {}", file.as_ref().display()); error!(context, "Cannot write key to {}", file.as_ref().display());

View File

@@ -1,6 +1,7 @@
//! Stress some functions for testing; if used as a lib, this file is obsolete. //! Stress some functions for testing; if used as a lib, this file is obsolete.
use std::collections::HashSet; use std::collections::HashSet;
use std::path::PathBuf;
use std::ptr; use std::ptr;
use tempfile::{tempdir, TempDir}; 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.dadada");
dc_delete_file(context, "$BLOBDIR/foobar-folder"); dc_delete_file(context, "$BLOBDIR/foobar-folder");
} }
dc_write_file( assert!(dc_write_file(context, "$BLOBDIR/foobar", b"content"));
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_file_exist(context, "$BLOBDIR/foobar",)); assert!(dc_file_exist(context, "$BLOBDIR/foobar",));
assert!(!dc_file_exist(context, "$BLOBDIR/foobarx")); 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 let abs_path = context
.get_blobdir() .get_blobdir()
@@ -87,41 +83,14 @@ unsafe fn stress_functions(context: &Context) {
assert!(dc_create_folder(context, "$BLOBDIR/foobar-folder")); assert!(dc_create_folder(context, "$BLOBDIR/foobar-folder"));
assert!(dc_file_exist(context, "$BLOBDIR/foobar-folder",)); assert!(dc_file_exist(context, "$BLOBDIR/foobar-folder",));
assert!(!dc_delete_file(context, "$BLOBDIR/foobar-folder")); assert!(!dc_delete_file(context, "$BLOBDIR/foobar-folder"));
let fn0: *mut libc::c_char = dc_get_fine_pathNfilename( let fn0 = dc_get_fine_path_filename(context, "$BLOBDIR", "foobar.dadada");
context, assert_eq!(fn0, PathBuf::from("$BLOBDIR/foobar.dadada"));
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
b"foobar.dadada\x00" as *const u8 as *const libc::c_char, assert!(dc_write_file(context, &fn0, b"content"));
); let fn1 = dc_get_fine_path_filename(context, "$BLOBDIR", "foobar.dadada");
assert!(!fn0.is_null()); assert_eq!(fn1, PathBuf::from("$BLOBDIR/foobar-1.dadada"));
assert_eq!(
strcmp( assert!(dc_delete_file(context, &fn0));
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 res = context.get_config(config::Config::SysConfigKeys).unwrap(); let res = context.get_config(config::Config::SysConfigKeys).unwrap();