refactor: drop libc based directory reading

This commit is contained in:
dignifiedquire
2019-05-29 20:21:59 +02:00
parent c9c3ac3c23
commit 62e54c7291
6 changed files with 303 additions and 362 deletions

View File

@@ -160,10 +160,7 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
let mut success: libc::c_int = 0i32; let mut success: libc::c_int = 0i32;
let mut real_spec: *mut libc::c_char = 0 as *mut libc::c_char; let mut real_spec: *mut libc::c_char = 0 as *mut libc::c_char;
let mut suffix: *mut libc::c_char = 0 as *mut libc::c_char; let mut suffix: *mut libc::c_char = 0 as *mut libc::c_char;
let mut dir: *mut DIR = 0 as *mut DIR;
let mut dir_entry: *mut dirent;
let mut read_cnt: libc::c_int = 0i32; let mut read_cnt: libc::c_int = 0i32;
let mut name: *mut libc::c_char;
if 0 == dc_sqlite3_is_open(&context.sql.clone().read().unwrap()) { if 0 == dc_sqlite3_is_open(&context.sql.clone().read().unwrap()) {
dc_log_error( dc_log_error(
context, context,
@@ -212,8 +209,9 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
current_block = 1622411330066726685; current_block = 1622411330066726685;
} else { } else {
/* import a directory */ /* import a directory */
dir = opendir(real_spec); let dir_name = std::path::Path::new(to_str(real_spec));
if dir.is_null() { let dir = std::fs::read_dir(dir_name);
if dir.is_err() {
dc_log_error( dc_log_error(
context, context,
0i32, 0i32,
@@ -223,22 +221,19 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
); );
current_block = 8522321847195001863; current_block = 8522321847195001863;
} else { } else {
loop { let dir = dir.unwrap();
dir_entry = readdir(dir); for entry in dir {
if dir_entry.is_null() { if entry.is_err() {
break; break;
} }
name = (*dir_entry).d_name.as_mut_ptr(); let entry = entry.unwrap();
if strlen(name) >= 4 let name_f = entry.file_name();
&& strcmp( let name = name_f.to_string_lossy();
&mut *name.offset(strlen(name).wrapping_sub(4) as isize), if name.ends_with(".eml") {
b".eml\x00" as *const u8 as *const libc::c_char,
) == 0i32
{
let path_plus_name: *mut libc::c_char = dc_mprintf( let path_plus_name: *mut libc::c_char = dc_mprintf(
b"%s/%s\x00" as *const u8 as *const libc::c_char, b"%s/%s\x00" as *const u8 as *const libc::c_char,
real_spec, real_spec,
name, to_cstring(name).as_ptr(),
); );
dc_log_info( dc_log_info(
context, context,
@@ -280,13 +275,11 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
} }
} }
} }
if !dir.is_null() {
closedir(dir);
}
free(real_spec as *mut libc::c_void); free(real_spec as *mut libc::c_void);
free(suffix as *mut libc::c_void); free(suffix as *mut libc::c_void);
return success; success
} }
unsafe fn log_msg(context: &Context, prefix: *const libc::c_char, msg: *mut dc_msg_t) { unsafe fn log_msg(context: &Context, prefix: *const libc::c_char, msg: *mut dc_msg_t) {
let contact: *mut dc_contact_t = dc_get_contact(context, dc_msg_get_from_id(msg)); let contact: *mut dc_contact_t = dc_get_contact(context, dc_msg_get_from_id(msg));
let contact_name: *mut libc::c_char = dc_contact_get_name(contact); let contact_name: *mut libc::c_char = dc_contact_get_name(contact);

View File

@@ -49,73 +49,63 @@ pub unsafe fn dc_imex_has_backup(
) -> *mut libc::c_char { ) -> *mut libc::c_char {
let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; let mut ret: *mut libc::c_char = 0 as *mut libc::c_char;
let mut ret_backup_time = 0; let mut ret_backup_time = 0;
let dir_handle: *mut DIR;
let mut dir_entry: *mut dirent;
let prefix_len = strlen(b"delta-chat\x00" as *const u8 as *const libc::c_char);
let suffix_len = strlen(b"bak\x00" as *const u8 as *const libc::c_char);
let mut curr_pathNfilename: *mut libc::c_char = 0 as *mut libc::c_char; let mut curr_pathNfilename: *mut libc::c_char = 0 as *mut libc::c_char;
let mut test_sql: Option<dc_sqlite3_t> = None; let mut test_sql: Option<dc_sqlite3_t> = None;
dir_handle = opendir(dir_name);
if dir_handle.is_null() { let dir = std::path::Path::new(to_str(dir_name));
dc_log_info(
context, if dir.is_dir() {
0i32, match std::fs::read_dir(dir) {
b"Backup check: Cannot open directory \"%s\".\x00" as *const u8 as *const libc::c_char, Ok(dir_handle) => {
dir_name, for entry in dir_handle {
); if entry.is_err() {
} else { continue;
loop { }
dir_entry = readdir(dir_handle); let entry = entry.unwrap();
if dir_entry.is_null() { let name_f = entry.file_name();
break; let name = name_f.to_string_lossy();
} if name.starts_with("delta-chat") && name.ends_with(".bak") {
let name: *const libc::c_char = (*dir_entry).d_name.as_mut_ptr(); free(curr_pathNfilename as *mut libc::c_void);
let name_len = strlen(name); curr_pathNfilename = dc_mprintf(
if name_len > prefix_len b"%s/%s\x00" as *const u8 as *const libc::c_char,
&& strncmp( dir_name,
name, to_cstring(name).as_ptr(),
b"delta-chat\x00" as *const u8 as *const libc::c_char, );
prefix_len, if test_sql.is_some() {
) == 0i32 let mut test_sql = test_sql.take().unwrap();
&& name_len > suffix_len dc_sqlite3_unref(context, &mut test_sql);
&& strncmp( }
&*name.offset((name_len - suffix_len - 1) as isize), let mut sql = dc_sqlite3_new();
b".bak\x00" as *const u8 as *const libc::c_char, if 0 != dc_sqlite3_open(context, &mut sql, curr_pathNfilename, 0x1i32) {
suffix_len, let curr_backup_time = dc_sqlite3_get_config_int(
) == 0i32 context,
{ &mut sql,
free(curr_pathNfilename as *mut libc::c_void); b"backup_time\x00" as *const u8 as *const libc::c_char,
curr_pathNfilename = dc_mprintf( 0,
b"%s/%s\x00" as *const u8 as *const libc::c_char, ) as u64;
dir_name, if curr_backup_time > 0 && curr_backup_time > ret_backup_time {
name, free(ret as *mut libc::c_void);
); ret = curr_pathNfilename;
if test_sql.is_some() { ret_backup_time = curr_backup_time;
let mut test_sql = test_sql.take().unwrap(); curr_pathNfilename = 0 as *mut libc::c_char
dc_sqlite3_unref(context, &mut test_sql); }
} }
let mut sql = dc_sqlite3_new(); test_sql = Some(sql);
if 0 != dc_sqlite3_open(context, &mut sql, curr_pathNfilename, 0x1i32) {
let curr_backup_time = dc_sqlite3_get_config_int(
context,
&mut sql,
b"backup_time\x00" as *const u8 as *const libc::c_char,
0i32,
) as u64;
if curr_backup_time > 0 && curr_backup_time > ret_backup_time {
free(ret as *mut libc::c_void);
ret = curr_pathNfilename;
ret_backup_time = curr_backup_time;
curr_pathNfilename = 0 as *mut libc::c_char
} }
} }
test_sql = Some(sql); }
Err(_) => {
dc_log_info(
context,
0i32,
b"Backup check: Cannot open directory \"%s\".\x00" as *const u8
as *const libc::c_char,
dir_name,
);
} }
} }
} }
if !dir_handle.is_null() {
closedir(dir_handle);
}
free(curr_pathNfilename as *mut libc::c_void); free(curr_pathNfilename as *mut libc::c_void);
if let Some(ref mut sql) = test_sql { if let Some(ref mut sql) = test_sql {
dc_sqlite3_unref(context, sql); dc_sqlite3_unref(context, sql);
@@ -1109,269 +1099,239 @@ The macro avoids weird values of 0% or 100% while still working. */
unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_int { unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_int {
let mut current_block: u64; let mut current_block: u64;
let mut success: libc::c_int = 0i32; let mut success: libc::c_int = 0i32;
let mut closed: libc::c_int = 0i32; let mut closed: libc::c_int;
let dest_pathNfilename: *mut libc::c_char;
let now = time();
let mut dir_handle: *mut DIR = 0 as *mut DIR;
let mut dir_entry: *mut dirent;
let prefix_len = strlen(b"delta-chat\x00" as *const u8 as *const libc::c_char);
let suffix_len = strlen(b"bak\x00" as *const u8 as *const libc::c_char);
let mut curr_pathNfilename: *mut libc::c_char = 0 as *mut libc::c_char; let mut curr_pathNfilename: *mut libc::c_char = 0 as *mut libc::c_char;
let mut buf: *mut libc::c_void = 0 as *mut libc::c_void; let mut buf: *mut libc::c_void = 0 as *mut libc::c_void;
let mut buf_bytes: size_t = 0i32 as size_t; let mut buf_bytes: size_t = 0i32 as size_t;
let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt;
let mut total_files_cnt: libc::c_int;
let mut processed_files_cnt: libc::c_int = 0i32;
let mut delete_dest_file: libc::c_int = 0i32; let mut delete_dest_file: libc::c_int = 0i32;
let mut dest_sql: Option<dc_sqlite3_t> = None; let mut dest_sql: Option<dc_sqlite3_t> = None;
/* get a fine backup file name (the name includes the date so that multiple backup instances are possible) // get a fine backup file name (the name includes the date so that multiple backup instances are possible)
FIXME: we should write to a temporary file first and rename it on success. this would guarantee the backup is complete. however, currently it is not clear it the import exists in the long run (may be replaced by a restore-from-imap)*/ // FIXME: we should write to a temporary file first and rename it on success. this would guarantee the backup is complete. however, currently it is not clear it the import exists in the long run (may be replaced by a restore-from-imap)
let now = time();
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 = to_cstring(res); let buffer = to_cstring(res);
dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer.as_ptr()); let dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer.as_ptr());
if dest_pathNfilename.is_null() { if dest_pathNfilename.is_null() {
dc_log_error( dc_log_error(
context, context,
0i32, 0i32,
b"Cannot get backup file name.\x00" as *const u8 as *const libc::c_char, b"Cannot get backup file name.\x00" as *const u8 as *const libc::c_char,
); );
} else {
dc_housekeeping(context); return success;
dc_sqlite3_try_execute( }
dc_housekeeping(context);
dc_sqlite3_try_execute(
context,
&context.sql.clone().read().unwrap(),
b"VACUUM;\x00" as *const u8 as *const libc::c_char,
);
dc_sqlite3_close(context, &mut context.sql.clone().write().unwrap());
closed = 1i32;
dc_log_info(
context,
0i32,
b"Backup \"%s\" to \"%s\".\x00" as *const u8 as *const libc::c_char,
context.get_dbfile(),
dest_pathNfilename,
);
if !(0 == dc_copy_file(context, context.get_dbfile(), dest_pathNfilename)) {
/* error already logged */
dc_sqlite3_open(
context, context,
&context.sql.clone().read().unwrap(), &mut context.sql.clone().write().unwrap(),
b"VACUUM;\x00" as *const u8 as *const libc::c_char,
);
dc_sqlite3_close(context, &mut context.sql.clone().write().unwrap());
closed = 1i32;
dc_log_info(
context,
0i32,
b"Backup \"%s\" to \"%s\".\x00" as *const u8 as *const libc::c_char,
context.get_dbfile(), context.get_dbfile(),
dest_pathNfilename, 0i32,
); );
if !(0 == dc_copy_file(context, context.get_dbfile(), dest_pathNfilename)) { closed = 0i32;
/* 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 mut sql = dc_sqlite3_new();
if 0 != dc_sqlite3_open(context, &mut sql, dest_pathNfilename, 0i32) {
/* error already logged */ /* error already logged */
dc_sqlite3_open( if 0 == dc_sqlite3_table_exists(
context, context,
&mut context.sql.clone().write().unwrap(), &mut sql,
context.get_dbfile(), b"backup_blobs\x00" as *const u8 as *const libc::c_char,
0i32, ) {
); if 0 ==
closed = 0i32; dc_sqlite3_execute(context, &mut sql,
/* 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) */ b"CREATE TABLE backup_blobs (id INTEGER PRIMARY KEY, file_name, file_content);\x00"
/*for logging only*/ as *const u8 as
let mut sql = dc_sqlite3_new(); *const libc::c_char) {
if 0 != dc_sqlite3_open(context, &mut sql, dest_pathNfilename, 0i32) {
/* error already logged */
if 0 == dc_sqlite3_table_exists(
context,
&mut sql,
b"backup_blobs\x00" as *const u8 as *const libc::c_char,
) {
if 0 ==
dc_sqlite3_execute(context, &mut sql,
b"CREATE TABLE backup_blobs (id INTEGER PRIMARY KEY, file_name, file_content);\x00"
as *const u8 as
*const libc::c_char) {
/* error already logged */ /* error already logged */
current_block = 11487273724841241105; current_block = 11487273724841241105;
} else { current_block = 14648156034262866959; } } else { current_block = 14648156034262866959; }
} else { } else {
current_block = 14648156034262866959; current_block = 14648156034262866959;
} }
match current_block { match current_block {
11487273724841241105 => {} 11487273724841241105 => {}
_ => { _ => {
total_files_cnt = 0i32; let mut total_files_cnt = 0;
dir_handle = opendir(context.get_blobdir()); let dir = std::path::Path::new(to_str(context.get_blobdir()));
if dir_handle.is_null() { let dir_handle = std::fs::read_dir(dir);
dc_log_error( if dir_handle.is_err() {
dc_log_error(
context,
0i32,
b"Backup: Cannot get info for blob-directory \"%s\".\x00" as *const u8
as *const libc::c_char,
context.get_blobdir(),
);
} else {
let dir_handle = dir_handle.unwrap();
total_files_cnt += dir_handle.filter(|r| r.is_ok()).count();
if total_files_cnt > 0 {
// scan directory, pass 2: copy files
let dir_handle = std::fs::read_dir(dir);
if dir_handle.is_err() {
dc_log_error(
context,
0i32,
b"Backup: Cannot copy from blob-directory \"%s\".\x00"
as *const u8
as *const libc::c_char,
context.get_blobdir(),
);
} else {
let dir_handle = dir_handle.unwrap();
stmt = dc_sqlite3_prepare(
context, context,
0i32, &mut sql,
b"Backup: Cannot get info for blob-directory \"%s\".\x00" b"INSERT INTO backup_blobs (file_name, file_content) VALUES (?, ?);\x00"
as *const u8 as *const u8 as
as *const libc::c_char, *const libc::c_char
context.get_blobdir(),
); );
} else {
loop { let mut processed_files_cnt = 0;
dir_entry = readdir(dir_handle); for entry in dir_handle {
if dir_entry.is_null() { if entry.is_err() {
break; current_block = 2631791190359682872;
} break;
total_files_cnt += 1 }
} let entry = entry.unwrap();
closedir(dir_handle); if context
dir_handle = 0 as *mut DIR; .running_state
if total_files_cnt > 0i32 { .clone()
/* scan directory, pass 2: copy files */ .read()
dir_handle = opendir(context.get_blobdir()); .unwrap()
if dir_handle.is_null() { .shall_stop_ongoing
dc_log_error( {
context, delete_dest_file = 1;
0i32, current_block = 11487273724841241105;
b"Backup: Cannot copy from blob-directory \"%s\".\x00" break;
as *const u8 } else {
as *const libc::c_char, processed_files_cnt += 1;
context.get_blobdir(), let mut permille =
); processed_files_cnt * 1000 / total_files_cnt;
current_block = 11487273724841241105; if permille < 10 {
} else { permille = 10;
stmt =
dc_sqlite3_prepare(
context,
&mut sql,
b"INSERT INTO backup_blobs (file_name, file_content) VALUES (?, ?);\x00"
as *const u8 as
*const libc::c_char);
loop {
dir_entry = readdir(dir_handle);
if dir_entry.is_null() {
current_block = 2631791190359682872;
break;
} }
if context if permille > 990 {
.running_state permille = 990;
.clone() }
.read() (context.cb)(
.unwrap() context,
.shall_stop_ongoing Event::IMEX_PROGRESS,
{ permille as uintptr_t,
delete_dest_file = 1i32; 0i32 as uintptr_t,
current_block = 11487273724841241105; );
break;
} else { let name_f = entry.file_name();
processed_files_cnt += 1; let name = name_f.to_string_lossy();
let mut permille: libc::c_int = if name.starts_with("delt-chat") && name.ends_with(".bak") {
processed_files_cnt * 1000i32 / total_files_cnt; // dc_log_info(context, 0, "Backup: Skipping \"%s\".", name);
if permille < 10i32 { free(curr_pathNfilename as *mut libc::c_void);
permille = 10i32 let name_c = to_cstring(name);
} curr_pathNfilename = dc_mprintf(
if permille > 990i32 { b"%s/%s\x00" as *const u8 as *const libc::c_char,
permille = 990i32 context.get_blobdir(),
} name_c.as_ptr(),
(context.cb)(
context,
Event::IMEX_PROGRESS,
permille as uintptr_t,
0i32 as uintptr_t,
); );
/* name without path; may also be `.` or `..` */ free(buf);
let name: *mut libc::c_char = if 0 == dc_read_file(
(*dir_entry).d_name.as_mut_ptr(); context,
let name_len = strlen(name); curr_pathNfilename,
if !(name_len == 1 &mut buf,
&& *name.offset(0isize) as libc::c_int &mut buf_bytes,
== '.' as i32 ) || buf.is_null()
|| name_len == 2 || buf_bytes <= 0
&& *name.offset(0isize) as libc::c_int
== '.' as i32
&& *name.offset(1isize) as libc::c_int
== '.' as i32
|| name_len > prefix_len
&& strncmp(
name,
b"delta-chat\x00" as *const u8
as *const libc::c_char,
prefix_len,
) == 0i32
&& name_len > suffix_len
&& strncmp(
&mut *name.offset(
(name_len - suffix_len - 1) as isize,
),
b".bak\x00" as *const u8
as *const libc::c_char,
suffix_len,
) == 0i32)
{ {
//dc_log_info(context, 0, "Backup: Skipping \"%s\".", name); continue;
free(curr_pathNfilename as *mut libc::c_void); }
curr_pathNfilename = dc_mprintf( sqlite3_bind_text(
b"%s/%s\x00" as *const u8 stmt,
as *const libc::c_char, 1i32,
context.get_blobdir(), name_c.as_ptr(),
name, -1i32,
); None,
free(buf); );
if 0 == dc_read_file( sqlite3_bind_blob(
context, stmt,
curr_pathNfilename, 2i32,
&mut buf, buf,
&mut buf_bytes, buf_bytes as libc::c_int,
) || buf.is_null() None,
|| buf_bytes <= 0 );
{ if sqlite3_step(stmt) != 101i32 {
continue; dc_log_error(
} context,
sqlite3_bind_text(stmt, 1i32, name, -1i32, None); 0i32,
sqlite3_bind_blob( b"Disk full? Cannot add file \"%s\" to backup.\x00"
stmt, as *const u8
2i32, as *const libc::c_char,
buf, curr_pathNfilename,
buf_bytes as libc::c_int, );
None, /* this is not recoverable! writing to the sqlite database should work! */
); current_block = 11487273724841241105;
if sqlite3_step(stmt) != 101i32 { break;
dc_log_error(context, } else {
0i32, sqlite3_reset(stmt);
b"Disk full? Cannot add file \"%s\" to backup.\x00"
as
*const u8
as
*const libc::c_char,
curr_pathNfilename);
/* this is not recoverable! writing to the sqlite database should work! */
current_block = 11487273724841241105;
break;
} else {
sqlite3_reset(stmt);
}
} }
} }
} }
} }
} else {
dc_log_info(
context,
0i32,
b"Backup: No files to copy.\x00" as *const u8
as *const libc::c_char,
context.get_blobdir(),
);
current_block = 2631791190359682872;
} }
match current_block { } else {
11487273724841241105 => {} dc_log_info(
_ => { context,
dc_sqlite3_set_config_int( 0i32,
context, b"Backup: No files to copy.\x00" as *const u8
&mut sql, as *const libc::c_char,
b"backup_time\x00" as *const u8 as *const libc::c_char, context.get_blobdir(),
now as int32_t, );
); current_block = 2631791190359682872;
(context.cb)( }
context, match current_block {
Event::IMEX_FILE_WRITTEN, 11487273724841241105 => {}
dest_pathNfilename as uintptr_t, _ => {
0i32 as uintptr_t, dc_sqlite3_set_config_int(
); context,
success = 1i32 &mut sql,
} b"backup_time\x00" as *const u8 as *const libc::c_char,
now as int32_t,
);
(context.cb)(
context,
Event::IMEX_FILE_WRITTEN,
dest_pathNfilename as uintptr_t,
0i32 as uintptr_t,
);
success = 1i32
} }
} }
} }
} }
} }
dest_sql = Some(sql);
} }
} dest_sql = Some(sql);
if !dir_handle.is_null() {
closedir(dir_handle);
} }
if 0 != closed { if 0 != closed {
dc_sqlite3_open( dc_sqlite3_open(
@@ -1407,8 +1367,6 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
Maybe we should make the "default" key handlong also a little bit smarter Maybe we should make the "default" key handlong also a little bit smarter
(currently, the last imported key is the standard key unless it contains the string "legacy" in its name) */ (currently, the last imported key is the standard key unless it contains the string "legacy" in its name) */
let mut imported_cnt: libc::c_int = 0i32; let mut imported_cnt: libc::c_int = 0i32;
let mut dir_handle = 0 as *mut DIR;
let mut dir_entry: *mut dirent;
let mut suffix: *mut libc::c_char = 0 as *mut libc::c_char; let mut suffix: *mut libc::c_char = 0 as *mut libc::c_char;
let mut path_plus_name: *mut libc::c_char = 0 as *mut libc::c_char; let mut path_plus_name: *mut libc::c_char = 0 as *mut libc::c_char;
let mut set_default: libc::c_int; let mut set_default: libc::c_int;
@@ -1420,8 +1378,9 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
// a pointer inside buf2, MUST NOT be free()'d // a pointer inside buf2, MUST NOT be free()'d
let mut buf2_headerline: *const libc::c_char = 0 as *const libc::c_char; let mut buf2_headerline: *const libc::c_char = 0 as *const libc::c_char;
if !dir_name.is_null() { if !dir_name.is_null() {
dir_handle = opendir(dir_name); let dir = std::path::Path::new(to_str(dir_name));
if dir_handle.is_null() { let dir_handle = std::fs::read_dir(dir);
if dir_handle.is_err() {
dc_log_error( dc_log_error(
context, context,
0i32, 0i32,
@@ -1429,13 +1388,16 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
dir_name, dir_name,
); );
} else { } else {
loop { let dir_handle = dir_handle.unwrap();
dir_entry = readdir(dir_handle); for entry in dir_handle {
if dir_entry.is_null() { if entry.is_err() {
break; break;
} }
let entry = entry.unwrap();
free(suffix as *mut libc::c_void); free(suffix as *mut libc::c_void);
suffix = dc_get_filesuffix_lc((*dir_entry).d_name.as_mut_ptr()); let name_f = entry.file_name();
let name_c = to_cstring(name_f.to_string_lossy());
suffix = dc_get_filesuffix_lc(name_c.as_ptr());
if suffix.is_null() if suffix.is_null()
|| strcmp(suffix, b"asc\x00" as *const u8 as *const libc::c_char) != 0i32 || strcmp(suffix, b"asc\x00" as *const u8 as *const libc::c_char) != 0i32
{ {
@@ -1445,7 +1407,7 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
path_plus_name = dc_mprintf( path_plus_name = dc_mprintf(
b"%s/%s\x00" as *const u8 as *const libc::c_char, b"%s/%s\x00" as *const u8 as *const libc::c_char,
dir_name, dir_name,
(*dir_entry).d_name.as_mut_ptr(), name_c.as_ptr(),
); );
dc_log_info( dc_log_info(
context, context,
@@ -1489,7 +1451,7 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
} }
set_default = 1i32; set_default = 1i32;
if !strstr( if !strstr(
(*dir_entry).d_name.as_mut_ptr(), name_c.as_ptr(),
b"legacy\x00" as *const u8 as *const libc::c_char, b"legacy\x00" as *const u8 as *const libc::c_char,
) )
.is_null() .is_null()
@@ -1518,9 +1480,7 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
} }
} }
} }
if !dir_handle.is_null() {
closedir(dir_handle);
}
free(suffix as *mut libc::c_void); free(suffix as *mut libc::c_void);
free(path_plus_name as *mut libc::c_void); free(path_plus_name as *mut libc::c_void);
free(buf as *mut libc::c_void); free(buf as *mut libc::c_void);

View File

@@ -1400,8 +1400,6 @@ pub unsafe fn dc_sqlite3_get_rowid2(
pub unsafe fn dc_housekeeping(context: &Context) { pub unsafe fn dc_housekeeping(context: &Context) {
let stmt; let stmt;
let dir_handle;
let mut dir_entry;
let mut files_in_use = HashSet::new(); let mut files_in_use = HashSet::new();
let mut path = 0 as *mut libc::c_char; let mut path = 0 as *mut libc::c_char;
let mut unreferenced_count = 0; let mut unreferenced_count = 0;
@@ -1454,8 +1452,9 @@ pub unsafe fn dc_housekeeping(context: &Context) {
files_in_use.len() as libc::c_int, files_in_use.len() as libc::c_int,
); );
/* go through directory and delete unused files */ /* go through directory and delete unused files */
dir_handle = opendir(context.get_blobdir()); let p = std::path::Path::new(to_str(context.get_blobdir()));
if dir_handle.is_null() { let dir_handle = std::fs::read_dir(p);
if dir_handle.is_err() {
dc_log_warning( dc_log_warning(
context, context,
0, 0,
@@ -1463,40 +1462,34 @@ pub unsafe fn dc_housekeeping(context: &Context) {
context.get_blobdir(), context.get_blobdir(),
); );
} else { } else {
let dir_handle = dir_handle.unwrap();
/* avoid deletion of files that are just created to build a message object */ /* avoid deletion of files that are just created to build a message object */
let diff = std::time::Duration::from_secs(60 * 60); let diff = std::time::Duration::from_secs(60 * 60);
let keep_files_newer_than = std::time::SystemTime::now().checked_sub(diff).unwrap(); let keep_files_newer_than = std::time::SystemTime::now().checked_sub(diff).unwrap();
loop { for entry in dir_handle {
dir_entry = readdir(dir_handle); if entry.is_err() {
if dir_entry.is_null() {
break; break;
} }
/* name without path or `.` or `..` */ let entry = entry.unwrap();
let name: *const libc::c_char = (*dir_entry).d_name.as_mut_ptr(); let name_f = entry.file_name();
let name_len: libc::c_int = strlen(name) as libc::c_int; let name_c = to_cstring(name_f.to_string_lossy());
if name_len == 1 && *name.offset(0isize) as libc::c_int == '.' as i32
|| name_len == 2 if is_file_in_use(&mut files_in_use, 0 as *const libc::c_char, name_c.as_ptr())
&& *name.offset(0isize) as libc::c_int == '.' as i32
&& *name.offset(1isize) as libc::c_int == '.' as i32
{
continue;
}
if is_file_in_use(&mut files_in_use, 0 as *const libc::c_char, name)
|| is_file_in_use( || is_file_in_use(
&mut files_in_use, &mut files_in_use,
b".increation\x00" as *const u8 as *const libc::c_char, b".increation\x00" as *const u8 as *const libc::c_char,
name, name_c.as_ptr(),
) )
|| is_file_in_use( || is_file_in_use(
&mut files_in_use, &mut files_in_use,
b".waveform\x00" as *const u8 as *const libc::c_char, b".waveform\x00" as *const u8 as *const libc::c_char,
name, name_c.as_ptr(),
) )
|| is_file_in_use( || is_file_in_use(
&mut files_in_use, &mut files_in_use,
b"-preview.jpg\x00" as *const u8 as *const libc::c_char, b"-preview.jpg\x00" as *const u8 as *const libc::c_char,
name, name_c.as_ptr(),
) )
{ {
continue; continue;
@@ -1506,7 +1499,7 @@ pub unsafe fn dc_housekeeping(context: &Context) {
path = dc_mprintf( path = dc_mprintf(
b"%s/%s\x00" as *const u8 as *const libc::c_char, b"%s/%s\x00" as *const u8 as *const libc::c_char,
context.get_blobdir(), context.get_blobdir(),
name, name_c.as_ptr(),
); );
match std::fs::metadata(std::ffi::CStr::from_ptr(path).to_str().unwrap()) { match std::fs::metadata(std::ffi::CStr::from_ptr(path).to_str().unwrap()) {
@@ -1525,7 +1518,7 @@ pub unsafe fn dc_housekeeping(context: &Context) {
b"Housekeeping: Keeping new unreferenced file #%i: %s\x00" as *const u8 b"Housekeeping: Keeping new unreferenced file #%i: %s\x00" as *const u8
as *const libc::c_char, as *const libc::c_char,
unreferenced_count, unreferenced_count,
name, name_c.as_ptr(),
); );
continue; continue;
} }
@@ -1538,14 +1531,12 @@ pub unsafe fn dc_housekeeping(context: &Context) {
b"Housekeeping: Deleting unreferenced file #%i: %s\x00" as *const u8 b"Housekeeping: Deleting unreferenced file #%i: %s\x00" as *const u8
as *const libc::c_char, as *const libc::c_char,
unreferenced_count, unreferenced_count,
name, name_c.as_ptr(),
); );
dc_delete_file(context, path); dc_delete_file(context, path);
} }
} }
if !dir_handle.is_null() {
closedir(dir_handle);
}
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
free(path as *mut libc::c_void); free(path as *mut libc::c_void);

View File

@@ -1271,21 +1271,20 @@ pub unsafe fn dc_create_folder(
let mut success = 0; let mut success = 0;
let pathNfilename_abs = dc_get_abs_path(context, pathNfilename); let pathNfilename_abs = dc_get_abs_path(context, pathNfilename);
{ {
let p = std::path::Path::new( let p = std::path::Path::new(to_str(pathNfilename_abs));
std::ffi::CStr::from_ptr(pathNfilename_abs)
.to_str()
.unwrap(),
);
if !p.exists() { if !p.exists() {
if mkdir(pathNfilename_abs, 0o755i32 as libc::mode_t) != 0i32 { match fs::create_dir_all(p) {
dc_log_warning( Ok(_) => {
context, success = 1;
0i32, }
b"Cannot create directory \"%s\".\x00" as *const u8 as *const libc::c_char, Err(_err) => {
pathNfilename, dc_log_warning(
); context,
} else { 0i32,
success = 1; b"Cannot create directory \"%s\".\x00" as *const u8 as *const libc::c_char,
pathNfilename,
);
}
} }
} else { } else {
success = 1; success = 1;

View File

@@ -68,7 +68,6 @@ pub type __uint16_t = libc::uint16_t;
pub type __int32_t = libc::int32_t; pub type __int32_t = libc::int32_t;
pub type __uint64_t = libc::uint64_t; pub type __uint64_t = libc::uint64_t;
pub type pid_t = libc::pid_t;
pub type size_t = libc::size_t; pub type size_t = libc::size_t;
pub type ssize_t = libc::ssize_t; pub type ssize_t = libc::ssize_t;
pub type uint32_t = libc::c_uint; pub type uint32_t = libc::c_uint;

View File

@@ -2,10 +2,9 @@ use crate::dc_strbuilder::dc_strbuilder_t;
use crate::types::*; use crate::types::*;
pub use libc::{ pub use libc::{
atoi, calloc, close, closedir, exit, fclose, fgets, fopen, fread, free, fseek, ftell, fwrite, atoi, calloc, exit, free, malloc, memcmp, memcpy, memmove, memset, realloc, strcat, strchr,
malloc, memcmp, memcpy, memmove, memset, mkdir, open, opendir, read, readdir, realloc, remove, strcmp, strcpy, strcspn, strlen, strncmp, strncpy, strrchr, strspn, strstr, strtol, system,
strcat, strchr, strcmp, strcpy, strcspn, strlen, strncmp, strncpy, strrchr, strspn, strstr, tolower, write,
strtol, system, tolower, write,
}; };
pub unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char { pub unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char {