@@ -46,6 +46,7 @@ pub trait UsbStorage {
4646 self . usb_write ( path, offset, data)
4747 }
4848 fn usb_delete ( & mut self , path : & str ) -> Result < ( ) , ImageError > ;
49+ fn usb_rmdir ( & mut self , path : & str ) -> Result < ( ) , ImageError > ;
4950 fn usb_rename ( & mut self , from : & str , to : & str ) -> Result < ( ) , ImageError > ;
5051 fn usb_mkdir ( & mut self , path : & str ) -> Result < ( ) , ImageError > ;
5152}
@@ -70,6 +71,13 @@ impl<F> SdImageSource<F>
7071where
7172 F : Filesystem + ' static ,
7273{
74+ fn join_usb_path ( dir : & str , name : & str ) -> String {
75+ if dir. is_empty ( ) || dir == "/" {
76+ return format ! ( "/{}" , name) ;
77+ }
78+ format ! ( "{}/{}" , dir. trim_end_matches( '/' ) , name)
79+ }
80+
7381 fn build_path ( path : & [ String ] , name : & str ) -> String {
7482 if path. is_empty ( ) {
7583 return name. to_string ( ) ;
@@ -253,8 +261,10 @@ where
253261 for < ' a > F :: File < ' a > : ' static ,
254262{
255263 fn usb_list ( & mut self , path : & str ) -> Result < Vec < UsbDirEntry > , ImageError > {
256- let dir = self . fs . open_directory ( path) . map_err ( |_| ImageError :: Io ) ?;
257- let listed = dir. list ( ) . map_err ( |_| ImageError :: Io ) ?;
264+ let listed = {
265+ let dir = self . fs . open_directory ( path) . map_err ( |_| ImageError :: Io ) ?;
266+ dir. list ( ) . map_err ( |_| ImageError :: Io ) ?
267+ } ;
258268 let mut out = Vec :: new ( ) ;
259269 for entry in listed {
260270 out. push ( UsbDirEntry {
@@ -361,6 +371,12 @@ where
361371 Ok ( ( ) )
362372 }
363373
374+ fn usb_rmdir ( & mut self , path : & str ) -> Result < ( ) , ImageError > {
375+ self . usb_delete_dir_recursive ( path) ?;
376+ self . fs . delete_file ( path) . map_err ( |_| ImageError :: Io ) ?;
377+ Ok ( ( ) )
378+ }
379+
364380 fn usb_rename ( & mut self , from : & str , to : & str ) -> Result < ( ) , ImageError > {
365381 self . fs . rename_file ( from, to) . map_err ( |_| ImageError :: Io )
366382 }
@@ -428,6 +444,34 @@ where
428444 . fs
429445 . delete_file ( & format ! ( "{}/{}" , cache_legacy, title) ) ;
430446 }
447+
448+ fn usb_delete_dir_recursive ( & mut self , path : & str ) -> Result < ( ) , ImageError >
449+ where
450+ F : UsbFsOps ,
451+ {
452+ let listed = {
453+ let dir = self . fs . open_directory ( path) . map_err ( |_| ImageError :: Io ) ?;
454+ dir. list ( ) . map_err ( |_| ImageError :: Io ) ?
455+ } ;
456+ let entries: Vec < ( String , bool ) > = listed
457+ . into_iter ( )
458+ . map ( |entry| ( entry. name ( ) . to_string ( ) , entry. is_directory ( ) ) )
459+ . collect ( ) ;
460+ for ( name, is_dir) in entries {
461+ if name == "." || name == ".." {
462+ continue ;
463+ }
464+ let full_path = Self :: join_usb_path ( path, & name) ;
465+ if is_dir {
466+ self . usb_delete_dir_recursive ( & full_path) ?;
467+ let _ = self . fs . delete_file ( & full_path) ;
468+ } else {
469+ let _ = self . fs . delete_file ( & full_path) ;
470+ self . cleanup_deleted_path_with_usb ( & full_path) ;
471+ }
472+ }
473+ Ok ( ( ) )
474+ }
431475}
432476
433477fn read_exact < R : Read + ?Sized > ( reader : & mut R , mut buf : & mut [ u8 ] ) -> Result < ( ) , ImageError > {
@@ -640,18 +684,27 @@ where
640684 for entry in listed {
641685 let name = entry. name ( ) . to_string ( ) ;
642686 let short = entry. short_name ( ) . to_string ( ) ;
687+ let upper = name. to_ascii_uppercase ( ) ;
688+ let short_upper = short. to_ascii_uppercase ( ) ;
689+ let short_is_hidden = short. starts_with ( '.' ) ;
643690 if !name. is_empty ( ) {
644691 self . short_names . push ( ( name. clone ( ) , short) ) ;
645692 }
646693 if name. is_empty ( )
647- || name == Self :: resume_filename ( )
648- || name == Self :: resume_filename_legacy ( )
649- || name == Self :: book_positions_filename ( )
650- || name == Self :: book_positions_filename_legacy ( )
651- || name == Self :: recent_entries_filename ( )
652- || name == Self :: recent_entries_filename_legacy ( )
653- || name == Self :: thumbnails_dirname ( )
654- || name == Self :: thumbnails_dirname_legacy ( )
694+ || name. starts_with ( '.' )
695+ || short_is_hidden
696+ || upper == Self :: resume_filename ( )
697+ || upper == Self :: resume_filename_legacy ( ) . to_ascii_uppercase ( )
698+ || upper == Self :: book_positions_filename ( )
699+ || upper == Self :: book_positions_filename_legacy ( ) . to_ascii_uppercase ( )
700+ || upper == Self :: recent_entries_filename ( )
701+ || upper == Self :: recent_entries_filename_legacy ( ) . to_ascii_uppercase ( )
702+ || upper == Self :: thumbnails_dirname ( )
703+ || upper == Self :: thumbnails_dirname_legacy ( ) . to_ascii_uppercase ( )
704+ || short_upper == Self :: resume_filename ( )
705+ || short_upper == Self :: book_positions_filename ( )
706+ || short_upper == Self :: recent_entries_filename ( )
707+ || short_upper == Self :: thumbnails_dirname ( )
655708 {
656709 continue ;
657710 }
0 commit comments