print-fs-fst.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import argparse
  2. import struct
  3. def read_entry(f) -> dict:
  4. name = struct.unpack_from("12s", f.read(12))[0]
  5. uid = struct.unpack_from(">I", f.read(4))[0]
  6. gid = struct.unpack_from(">H", f.read(2))[0]
  7. is_file = struct.unpack_from("?", f.read(1))[0]
  8. modes = struct.unpack_from("BBB", f.read(3))
  9. attr = struct.unpack_from("B", f.read(2))[0]
  10. x3 = struct.unpack_from(">I", f.read(4))[0]
  11. num_children = struct.unpack_from(">I", f.read(4))[0]
  12. children = []
  13. for i in range(num_children):
  14. children.append(read_entry(f))
  15. return {
  16. "name": name,
  17. "uid": uid,
  18. "gid": gid,
  19. "is_file": is_file,
  20. "modes": modes,
  21. "attr": attr,
  22. "x3": x3,
  23. "children": children,
  24. }
  25. COLOR_RESET = "\x1b[0;00m"
  26. BOLD = "\x1b[0;37m"
  27. COLOR_BLUE = "\x1b[1;34m"
  28. COLOR_GREEN = "\x1b[0;32m"
  29. def print_entry(entry, indent) -> None:
  30. mode_str = {0: "--", 1: "r-", 2: "-w", 3: "rw"}
  31. sp = ' ' * indent
  32. color = BOLD if entry["is_file"] else COLOR_BLUE
  33. owner = f"{COLOR_GREEN}{entry['uid']:04x}{COLOR_RESET}:{entry['gid']:04x}"
  34. attrs = f"{''.join(mode_str[mode] for mode in entry['modes'])}"
  35. other_attrs = f"{entry['attr']} {entry['x3']}"
  36. print(f"{sp}{color}{entry['name'].decode()}{COLOR_RESET} [{owner} {attrs} {other_attrs}]")
  37. for child in entry["children"]:
  38. print_entry(child, indent + 2)
  39. def main() -> None:
  40. parser = argparse.ArgumentParser(description="Prints a FST in a tree-like format.")
  41. parser.add_argument("file")
  42. args = parser.parse_args()
  43. with open(args.file, "rb") as f:
  44. root = read_entry(f)
  45. print_entry(root, 0)
  46. main()