59 lines
1.6 KiB
Python
59 lines
1.6 KiB
Python
|
import argparse
|
||
|
import struct
|
||
|
|
||
|
def read_entry(f) -> dict:
|
||
|
name = struct.unpack_from("12s", f.read(12))[0]
|
||
|
uid = struct.unpack_from(">I", f.read(4))[0]
|
||
|
gid = struct.unpack_from(">H", f.read(2))[0]
|
||
|
is_file = struct.unpack_from("?", f.read(1))[0]
|
||
|
modes = struct.unpack_from("BBB", f.read(3))
|
||
|
attr = struct.unpack_from("B", f.read(2))[0]
|
||
|
x3 = struct.unpack_from(">I", f.read(4))[0]
|
||
|
num_children = struct.unpack_from(">I", f.read(4))[0]
|
||
|
|
||
|
children = []
|
||
|
for i in range(num_children):
|
||
|
children.append(read_entry(f))
|
||
|
|
||
|
return {
|
||
|
"name": name,
|
||
|
"uid": uid,
|
||
|
"gid": gid,
|
||
|
"is_file": is_file,
|
||
|
"modes": modes,
|
||
|
"attr": attr,
|
||
|
"x3": x3,
|
||
|
"children": children,
|
||
|
}
|
||
|
|
||
|
COLOR_RESET = "\x1b[0;00m"
|
||
|
BOLD = "\x1b[0;37m"
|
||
|
COLOR_BLUE = "\x1b[1;34m"
|
||
|
COLOR_GREEN = "\x1b[0;32m"
|
||
|
|
||
|
def print_entry(entry, indent) -> None:
|
||
|
mode_str = {0: "--", 1: "r-", 2: "-w", 3: "rw"}
|
||
|
|
||
|
sp = ' ' * indent
|
||
|
color = BOLD if entry["is_file"] else COLOR_BLUE
|
||
|
|
||
|
owner = f"{COLOR_GREEN}{entry['uid']:04x}{COLOR_RESET}:{entry['gid']:04x}"
|
||
|
attrs = f"{''.join(mode_str[mode] for mode in entry['modes'])}"
|
||
|
other_attrs = f"{entry['attr']} {entry['x3']}"
|
||
|
|
||
|
print(f"{sp}{color}{entry['name'].decode()}{COLOR_RESET} [{owner} {attrs} {other_attrs}]")
|
||
|
for child in entry["children"]:
|
||
|
print_entry(child, indent + 2)
|
||
|
|
||
|
def main() -> None:
|
||
|
parser = argparse.ArgumentParser(description="Prints a FST in a tree-like format.")
|
||
|
parser.add_argument("file")
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
with open(args.file, "rb") as f:
|
||
|
root = read_entry(f)
|
||
|
|
||
|
print_entry(root, 0)
|
||
|
|
||
|
main()
|