diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 1a345599e..4e41b3a7b 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -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 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 dir: *mut DIR = 0 as *mut DIR; - let mut dir_entry: *mut dirent; 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()) { dc_log_error( context, @@ -212,8 +209,9 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int current_block = 1622411330066726685; } else { /* import a directory */ - dir = opendir(real_spec); - if dir.is_null() { + let dir_name = std::path::Path::new(to_str(real_spec)); + let dir = std::fs::read_dir(dir_name); + if dir.is_err() { dc_log_error( context, 0i32, @@ -223,22 +221,19 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int ); current_block = 8522321847195001863; } else { - loop { - dir_entry = readdir(dir); - if dir_entry.is_null() { + let dir = dir.unwrap(); + for entry in dir { + if entry.is_err() { break; } - name = (*dir_entry).d_name.as_mut_ptr(); - if strlen(name) >= 4 - && strcmp( - &mut *name.offset(strlen(name).wrapping_sub(4) as isize), - b".eml\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - { + let entry = entry.unwrap(); + let name_f = entry.file_name(); + let name = name_f.to_string_lossy(); + if name.ends_with(".eml") { let path_plus_name: *mut libc::c_char = dc_mprintf( b"%s/%s\x00" as *const u8 as *const libc::c_char, real_spec, - name, + to_cstring(name).as_ptr(), ); dc_log_info( 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(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) { 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); diff --git a/src/dc_imex.rs b/src/dc_imex.rs index 146ded76f..489d08bad 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -49,73 +49,63 @@ pub unsafe fn dc_imex_has_backup( ) -> *mut libc::c_char { let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; 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 test_sql: Option = None; - dir_handle = opendir(dir_name); - if dir_handle.is_null() { - dc_log_info( - context, - 0i32, - b"Backup check: Cannot open directory \"%s\".\x00" as *const u8 as *const libc::c_char, - dir_name, - ); - } else { - loop { - dir_entry = readdir(dir_handle); - if dir_entry.is_null() { - break; - } - let name: *const libc::c_char = (*dir_entry).d_name.as_mut_ptr(); - let name_len = strlen(name); - if 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( - &*name.offset((name_len - suffix_len - 1) as isize), - b".bak\x00" as *const u8 as *const libc::c_char, - suffix_len, - ) == 0i32 - { - free(curr_pathNfilename as *mut libc::c_void); - curr_pathNfilename = dc_mprintf( - b"%s/%s\x00" as *const u8 as *const libc::c_char, - dir_name, - name, - ); - if test_sql.is_some() { - let mut test_sql = test_sql.take().unwrap(); - dc_sqlite3_unref(context, &mut test_sql); - } - let mut sql = dc_sqlite3_new(); - 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 + + let dir = std::path::Path::new(to_str(dir_name)); + + if dir.is_dir() { + match std::fs::read_dir(dir) { + Ok(dir_handle) => { + for entry in dir_handle { + if entry.is_err() { + continue; + } + let entry = entry.unwrap(); + let name_f = entry.file_name(); + let name = name_f.to_string_lossy(); + if name.starts_with("delta-chat") && name.ends_with(".bak") { + free(curr_pathNfilename as *mut libc::c_void); + curr_pathNfilename = dc_mprintf( + b"%s/%s\x00" as *const u8 as *const libc::c_char, + dir_name, + to_cstring(name).as_ptr(), + ); + if test_sql.is_some() { + let mut test_sql = test_sql.take().unwrap(); + dc_sqlite3_unref(context, &mut test_sql); + } + let mut sql = dc_sqlite3_new(); + 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, + 0, + ) 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); } } - 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); if let Some(ref mut sql) = test_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 { let mut current_block: u64; let mut success: libc::c_int = 0i32; - let mut closed: libc::c_int = 0i32; - 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 closed: libc::c_int; + 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_bytes: size_t = 0i32 as size_t; 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 dest_sql: Option = None; - /* 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)*/ + // 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) + let now = time(); let res = chrono::NaiveDateTime::from_timestamp(now as i64, 0) .format("delta-chat-%Y-%m-%d.bak") .to_string(); 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() { dc_log_error( context, 0i32, b"Cannot get backup file name.\x00" as *const u8 as *const libc::c_char, ); - } else { - dc_housekeeping(context); - dc_sqlite3_try_execute( + + return success; + } + + 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.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, + &mut context.sql.clone().write().unwrap(), 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 */ - dc_sqlite3_open( + if 0 == dc_sqlite3_table_exists( context, - &mut context.sql.clone().write().unwrap(), - context.get_dbfile(), - 0i32, - ); - 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 */ - 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) { + &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 */ current_block = 11487273724841241105; } else { current_block = 14648156034262866959; } - } else { - current_block = 14648156034262866959; - } - match current_block { - 11487273724841241105 => {} - _ => { - total_files_cnt = 0i32; - dir_handle = opendir(context.get_blobdir()); - if dir_handle.is_null() { - dc_log_error( + } else { + current_block = 14648156034262866959; + } + match current_block { + 11487273724841241105 => {} + _ => { + let mut total_files_cnt = 0; + let dir = std::path::Path::new(to_str(context.get_blobdir())); + let dir_handle = std::fs::read_dir(dir); + 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, - 0i32, - b"Backup: Cannot get info for blob-directory \"%s\".\x00" - as *const u8 - as *const libc::c_char, - context.get_blobdir(), + &mut sql, + b"INSERT INTO backup_blobs (file_name, file_content) VALUES (?, ?);\x00" + as *const u8 as + *const libc::c_char ); - } else { - loop { - dir_entry = readdir(dir_handle); - if dir_entry.is_null() { - break; - } - total_files_cnt += 1 - } - closedir(dir_handle); - dir_handle = 0 as *mut DIR; - if total_files_cnt > 0i32 { - /* scan directory, pass 2: copy files */ - dir_handle = opendir(context.get_blobdir()); - if dir_handle.is_null() { - 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(), - ); - current_block = 11487273724841241105; - } else { - 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; + + let mut processed_files_cnt = 0; + for entry in dir_handle { + if entry.is_err() { + current_block = 2631791190359682872; + break; + } + let entry = entry.unwrap(); + if context + .running_state + .clone() + .read() + .unwrap() + .shall_stop_ongoing + { + delete_dest_file = 1; + current_block = 11487273724841241105; + break; + } else { + processed_files_cnt += 1; + let mut permille = + processed_files_cnt * 1000 / total_files_cnt; + if permille < 10 { + permille = 10; } - if context - .running_state - .clone() - .read() - .unwrap() - .shall_stop_ongoing - { - delete_dest_file = 1i32; - current_block = 11487273724841241105; - break; - } else { - processed_files_cnt += 1; - let mut permille: libc::c_int = - processed_files_cnt * 1000i32 / total_files_cnt; - if permille < 10i32 { - permille = 10i32 - } - if permille > 990i32 { - permille = 990i32 - } - (context.cb)( - context, - Event::IMEX_PROGRESS, - permille as uintptr_t, - 0i32 as uintptr_t, + if permille > 990 { + permille = 990; + } + (context.cb)( + context, + Event::IMEX_PROGRESS, + permille as uintptr_t, + 0i32 as uintptr_t, + ); + + let name_f = entry.file_name(); + let name = name_f.to_string_lossy(); + if name.starts_with("delt-chat") && name.ends_with(".bak") { + // dc_log_info(context, 0, "Backup: Skipping \"%s\".", name); + free(curr_pathNfilename as *mut libc::c_void); + let name_c = to_cstring(name); + curr_pathNfilename = dc_mprintf( + b"%s/%s\x00" as *const u8 as *const libc::c_char, + context.get_blobdir(), + name_c.as_ptr(), ); - /* name without path; may also be `.` or `..` */ - let name: *mut libc::c_char = - (*dir_entry).d_name.as_mut_ptr(); - let name_len = strlen(name); - if !(name_len == 1 - && *name.offset(0isize) as libc::c_int - == '.' as i32 - || name_len == 2 - && *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) + free(buf); + if 0 == dc_read_file( + context, + curr_pathNfilename, + &mut buf, + &mut buf_bytes, + ) || buf.is_null() + || buf_bytes <= 0 { - //dc_log_info(context, 0, "Backup: Skipping \"%s\".", name); - free(curr_pathNfilename as *mut libc::c_void); - curr_pathNfilename = dc_mprintf( - b"%s/%s\x00" as *const u8 - as *const libc::c_char, - context.get_blobdir(), - name, - ); - free(buf); - if 0 == dc_read_file( - context, - curr_pathNfilename, - &mut buf, - &mut buf_bytes, - ) || buf.is_null() - || buf_bytes <= 0 - { - continue; - } - sqlite3_bind_text(stmt, 1i32, name, -1i32, None); - sqlite3_bind_blob( - stmt, - 2i32, - buf, - buf_bytes as libc::c_int, - None, - ); - if sqlite3_step(stmt) != 101i32 { - dc_log_error(context, - 0i32, - 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); - } + continue; + } + sqlite3_bind_text( + stmt, + 1i32, + name_c.as_ptr(), + -1i32, + None, + ); + sqlite3_bind_blob( + stmt, + 2i32, + buf, + buf_bytes as libc::c_int, + None, + ); + if sqlite3_step(stmt) != 101i32 { + dc_log_error( + context, + 0i32, + 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 { - 11487273724841241105 => {} - _ => { - dc_sqlite3_set_config_int( - context, - &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 - } + } 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 { + 11487273724841241105 => {} + _ => { + dc_sqlite3_set_config_int( + context, + &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); } - } - if !dir_handle.is_null() { - closedir(dir_handle); + dest_sql = Some(sql); } if 0 != closed { 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 (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 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 path_plus_name: *mut libc::c_char = 0 as *mut libc::c_char; 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 let mut buf2_headerline: *const libc::c_char = 0 as *const libc::c_char; if !dir_name.is_null() { - dir_handle = opendir(dir_name); - if dir_handle.is_null() { + let dir = std::path::Path::new(to_str(dir_name)); + let dir_handle = std::fs::read_dir(dir); + if dir_handle.is_err() { dc_log_error( context, 0i32, @@ -1429,13 +1388,16 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> dir_name, ); } else { - loop { - dir_entry = readdir(dir_handle); - if dir_entry.is_null() { + let dir_handle = dir_handle.unwrap(); + for entry in dir_handle { + if entry.is_err() { break; } + let entry = entry.unwrap(); 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() || 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( b"%s/%s\x00" as *const u8 as *const libc::c_char, dir_name, - (*dir_entry).d_name.as_mut_ptr(), + name_c.as_ptr(), ); dc_log_info( context, @@ -1489,7 +1451,7 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> } set_default = 1i32; if !strstr( - (*dir_entry).d_name.as_mut_ptr(), + name_c.as_ptr(), b"legacy\x00" as *const u8 as *const libc::c_char, ) .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(path_plus_name as *mut libc::c_void); free(buf as *mut libc::c_void); diff --git a/src/dc_sqlite3.rs b/src/dc_sqlite3.rs index 240403cc6..84230099f 100644 --- a/src/dc_sqlite3.rs +++ b/src/dc_sqlite3.rs @@ -1400,8 +1400,6 @@ pub unsafe fn dc_sqlite3_get_rowid2( pub unsafe fn dc_housekeeping(context: &Context) { let stmt; - let dir_handle; - let mut dir_entry; let mut files_in_use = HashSet::new(); let mut path = 0 as *mut libc::c_char; let mut unreferenced_count = 0; @@ -1454,8 +1452,9 @@ pub unsafe fn dc_housekeeping(context: &Context) { files_in_use.len() as libc::c_int, ); /* go through directory and delete unused files */ - dir_handle = opendir(context.get_blobdir()); - if dir_handle.is_null() { + let p = std::path::Path::new(to_str(context.get_blobdir())); + let dir_handle = std::fs::read_dir(p); + if dir_handle.is_err() { dc_log_warning( context, 0, @@ -1463,40 +1462,34 @@ pub unsafe fn dc_housekeeping(context: &Context) { context.get_blobdir(), ); } else { + let dir_handle = dir_handle.unwrap(); /* avoid deletion of files that are just created to build a message object */ let diff = std::time::Duration::from_secs(60 * 60); let keep_files_newer_than = std::time::SystemTime::now().checked_sub(diff).unwrap(); - loop { - dir_entry = readdir(dir_handle); - if dir_entry.is_null() { + for entry in dir_handle { + if entry.is_err() { break; } - /* name without path or `.` or `..` */ - let name: *const libc::c_char = (*dir_entry).d_name.as_mut_ptr(); - let name_len: libc::c_int = strlen(name) as libc::c_int; - if name_len == 1 && *name.offset(0isize) as libc::c_int == '.' as i32 - || name_len == 2 - && *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) + let entry = entry.unwrap(); + let name_f = entry.file_name(); + let name_c = to_cstring(name_f.to_string_lossy()); + + if is_file_in_use(&mut files_in_use, 0 as *const libc::c_char, name_c.as_ptr()) || is_file_in_use( &mut files_in_use, b".increation\x00" as *const u8 as *const libc::c_char, - name, + name_c.as_ptr(), ) || is_file_in_use( &mut files_in_use, b".waveform\x00" as *const u8 as *const libc::c_char, - name, + name_c.as_ptr(), ) || is_file_in_use( &mut files_in_use, b"-preview.jpg\x00" as *const u8 as *const libc::c_char, - name, + name_c.as_ptr(), ) { continue; @@ -1506,7 +1499,7 @@ pub unsafe fn dc_housekeeping(context: &Context) { path = dc_mprintf( b"%s/%s\x00" as *const u8 as *const libc::c_char, context.get_blobdir(), - name, + name_c.as_ptr(), ); 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 as *const libc::c_char, unreferenced_count, - name, + name_c.as_ptr(), ); continue; } @@ -1538,14 +1531,12 @@ pub unsafe fn dc_housekeeping(context: &Context) { b"Housekeeping: Deleting unreferenced file #%i: %s\x00" as *const u8 as *const libc::c_char, unreferenced_count, - name, + name_c.as_ptr(), ); dc_delete_file(context, path); } } - if !dir_handle.is_null() { - closedir(dir_handle); - } + sqlite3_finalize(stmt); free(path as *mut libc::c_void); diff --git a/src/dc_tools.rs b/src/dc_tools.rs index fa268dc2e..6385d15a6 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -1271,21 +1271,20 @@ pub unsafe fn dc_create_folder( let mut success = 0; let pathNfilename_abs = dc_get_abs_path(context, pathNfilename); { - let p = std::path::Path::new( - std::ffi::CStr::from_ptr(pathNfilename_abs) - .to_str() - .unwrap(), - ); + let p = std::path::Path::new(to_str(pathNfilename_abs)); if !p.exists() { - if mkdir(pathNfilename_abs, 0o755i32 as libc::mode_t) != 0i32 { - dc_log_warning( - context, - 0i32, - b"Cannot create directory \"%s\".\x00" as *const u8 as *const libc::c_char, - pathNfilename, - ); - } else { - success = 1; + match fs::create_dir_all(p) { + Ok(_) => { + success = 1; + } + Err(_err) => { + dc_log_warning( + context, + 0i32, + b"Cannot create directory \"%s\".\x00" as *const u8 as *const libc::c_char, + pathNfilename, + ); + } } } else { success = 1; diff --git a/src/types.rs b/src/types.rs index bb9a03af0..60ea7df64 100644 --- a/src/types.rs +++ b/src/types.rs @@ -68,7 +68,6 @@ pub type __uint16_t = libc::uint16_t; pub type __int32_t = libc::int32_t; pub type __uint64_t = libc::uint64_t; -pub type pid_t = libc::pid_t; pub type size_t = libc::size_t; pub type ssize_t = libc::ssize_t; pub type uint32_t = libc::c_uint; diff --git a/src/x.rs b/src/x.rs index a28c8fbd3..0c21e8e05 100644 --- a/src/x.rs +++ b/src/x.rs @@ -2,10 +2,9 @@ use crate::dc_strbuilder::dc_strbuilder_t; use crate::types::*; pub use libc::{ - atoi, calloc, close, closedir, exit, fclose, fgets, fopen, fread, free, fseek, ftell, fwrite, - malloc, memcmp, memcpy, memmove, memset, mkdir, open, opendir, read, readdir, realloc, remove, - strcat, strchr, strcmp, strcpy, strcspn, strlen, strncmp, strncpy, strrchr, strspn, strstr, - strtol, system, tolower, write, + atoi, calloc, exit, free, malloc, memcmp, memcpy, memmove, memset, realloc, strcat, strchr, + strcmp, strcpy, strcspn, strlen, strncmp, strncpy, strrchr, strspn, strstr, strtol, system, + tolower, write, }; pub unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char {