1919
2020from __future__ import annotations
2121import os
22+ from pathlib import PurePath
2223import time
2324from typing import TYPE_CHECKING
2425from ubireader .ubifs .decrypt import decrypt_symlink_target
2829from ubireader .debug import error
2930
3031if TYPE_CHECKING :
31- from collections .abc import Mapping
32+ from collections .abc import Mapping , Sequence
3233 from ubireader .ubifs import ubifs as Ubifs , nodes
3334 from ubireader .ubifs .walk import _Inode
3435
35- def list_files (ubifs : Ubifs , list_path : str ) -> None :
36- pathnames = list_path .split ("/" )
37- pnames : list [str ] = []
38- for i in pathnames :
39- if len (i ) > 0 :
40- pnames .append (i )
36+ def list_files (ubifs : Ubifs , list_path : PurePath | str , * , recursive : bool = False ) -> None :
37+ list_path = PurePath (list_path )
38+ pnames = [part for part in list_path .parts if part != '/' ]
4139 try :
4240 inodes : dict [int , _Inode ] = {}
4341 bad_blocks : list [int ] = []
@@ -55,8 +53,16 @@ def list_files(ubifs: Ubifs, list_path: str) -> None:
5553 if not 'dent' in inodes [inum ]:
5654 return
5755
58- for dent in inodes [inum ]['dent' ]:
59- print_dent (ubifs , inodes , dent , longts = False )
56+ for dent in inodes [inum ].get ('dent' , []):
57+ print_dent (
58+ ubifs ,
59+ inodes ,
60+ dent ,
61+ longts = False ,
62+ recursive = recursive ,
63+ # Only show absolute paths if recursive
64+ dent_path = (list_path / dent .name ) if recursive else None ,
65+ )
6066
6167 if len (bad_blocks ):
6268 error (list_files , 'Warn' , 'Data may be missing or corrupted, bad blocks, LEB [%s]' % ',' .join (map (str , bad_blocks )))
@@ -102,10 +108,10 @@ def copy_file(ubifs: Ubifs, filepath: str, destpath: str) -> bool:
102108 return False
103109
104110
105- def find_dir (inodes : Mapping [int , _Inode ], inum : int , names : list [str ], idx : int ) -> int | None :
111+ def find_dir (inodes : Mapping [int , _Inode ], inum : int , names : Sequence [str ], idx : int ) -> int | None :
106112 if len (names ) == 0 :
107113 return 1
108- for dent in inodes [inum ][ 'dent' ] :
114+ for dent in inodes [inum ]. get ( 'dent' , []) :
109115 if dent .name == names [idx ]:
110116 if len (names ) == idx + 1 :
111117 return dent .inum
@@ -114,8 +120,21 @@ def find_dir(inodes: Mapping[int, _Inode], inum: int, names: list[str], idx: int
114120 return None
115121
116122
117- def print_dent (ubifs : Ubifs , inodes : Mapping [int , _Inode ], dent_node : nodes .dent_node , long : bool = True , longts : bool = False ) -> None :
123+ def print_dent (
124+ ubifs : Ubifs ,
125+ inodes : Mapping [int , _Inode ],
126+ dent_node : nodes .dent_node ,
127+ long : bool = True ,
128+ longts : bool = False ,
129+ * ,
130+ recursive : bool = False ,
131+ # Path of the directory entry
132+ dent_path : PurePath | None = None ,
133+ ) -> None :
118134 inode = inodes [dent_node .inum ]
135+ # Display the full path if path is set, otherwise just the name.
136+ display_path = str (dent_path ) if dent_path is not None else dent_node .name
137+
119138 if long :
120139 fl = file_leng (ubifs , inode )
121140
@@ -128,10 +147,21 @@ def print_dent(ubifs: Ubifs, inodes: Mapping[int, _Inode], dent_node: nodes.dent
128147 else :
129148 mtime = time .strftime ("%b %d %H:%M" , time .gmtime (inode ['ino' ].mtime_sec ))
130149
131- print ('%6o %2d %s %s %7d %s %s%s' % (inode ['ino' ].mode , inode ['ino' ].nlink , inode ['ino' ].uid , inode ['ino' ].gid , fl , mtime , dent_node . name , lnk ))
150+ print ('%6o %2d %s %s %7d %s %s%s' % (inode ['ino' ].mode , inode ['ino' ].nlink , inode ['ino' ].uid , inode ['ino' ].gid , fl , mtime , display_path , lnk ))
132151 else :
133- print (dent_node .name )
134-
152+ print (display_path )
153+
154+ if recursive and dent_node .type == UBIFS_ITYPE_DIR :
155+ for dnode in inode .get ('dent' , []):
156+ print_dent (
157+ ubifs ,
158+ inodes ,
159+ dnode ,
160+ long = long ,
161+ longts = longts ,
162+ recursive = recursive ,
163+ dent_path = dent_path / dnode .name if dent_path is not None else None ,
164+ )
135165
136166def file_leng (ubifs : Ubifs , inode : _Inode ) -> int :
137167 fl = 0
0 commit comments