Files
terminal_worse/env/ardeb
T

72 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""Minimal ar archive packer/extractor for .deb files on a-Shell.
Usage:
ardeb pack <out.ar> <file> [file ...]
ardeb extract <in.ar> <dest-dir>
"""
import os
import sys
def pack(out_path, files):
with open(out_path, "wb") as out:
out.write(b"!<arch>\n")
for path in files:
data = open(path, "rb").read()
name = os.path.basename(path)
if len(name) > 15:
raise SystemExit("ardeb: member name too long: " + name)
header = (
name.ljust(16)
+ "0".ljust(12)
+ "0".ljust(6)
+ "0".ljust(6)
+ "100644".ljust(8)
+ str(len(data)).ljust(10)
+ "`\n"
).encode("ascii")
out.write(header)
out.write(data)
if len(data) & 1:
out.write(b"\n")
def extract(archive, dest):
data = open(archive, "rb").read()
if not data.startswith(b"!<arch>\n"):
raise SystemExit("ardeb: not an ar archive")
os.makedirs(dest, exist_ok=True)
pos = 8
while pos + 60 <= len(data):
header = data[pos:pos + 60]
pos += 60
name = header[:16].decode("ascii", "ignore").strip().rstrip("/")
if not name:
continue
try:
size = int(header[48:58].decode("ascii", "ignore").strip() or "0")
except ValueError:
size = 0
body = data[pos:pos + size]
pos += size + (size & 1)
if name in (".", ".."):
continue
open(os.path.join(dest, name), "wb").write(body)
def main():
if len(sys.argv) < 4:
raise SystemExit(__doc__)
if sys.argv[1] == "pack":
pack(sys.argv[2], sys.argv[3:])
elif sys.argv[1] == "extract":
extract(sys.argv[2], sys.argv[3])
else:
raise SystemExit(__doc__)
if __name__ == "__main__":
main()