diff --git a/Tools/print-fs-fst.py b/Tools/print-fs-fst.py new file mode 100644 index 0000000000..8b88155e4a --- /dev/null +++ b/Tools/print-fs-fst.py @@ -0,0 +1,58 @@ +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()