1
0
mirror of https://github.com/cahirwpz/amigaos-cross-toolchain synced 2025-11-21 01:37:26 +00:00

Read and list AR archive.

This commit is contained in:
Krystian Bacławski
2013-07-19 15:38:38 +02:00
parent 3b3147d821
commit 8eda91a613
2 changed files with 60 additions and 0 deletions

12
tools/lsar.py Executable file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env python2.7 -B
import sys
from objtools import ar
if __name__ == '__main__':
for path in sys.argv[1:]:
print '%s:' % path
for num, entry in enumerate(ar.ReadFile(path), start=1):
print '%5d:' % num, entry.name, '(length: %d)' % len(entry.data)
print ''

48
tools/objtools/ar.py Normal file
View File

@ -0,0 +1,48 @@
import os
import struct
from collections import namedtuple
class ArEntry(namedtuple('ArEntry',
'name modtime owner group mode data')):
@classmethod
def decode(cls, ar):
name, modtime, owner, group, mode, length, magic = \
struct.unpack('16s12s6s6s8s10s2s', ar.read(60))
length = int(length.strip())
modtime = int(modtime.strip())
owner = int(owner.strip() or '0')
group = int(group.strip() or '0')
mode = mode.strip() or '100644'
if name.startswith('#1/'):
name_length = int(name[3:])
name = ar.read(name_length).strip('\0')
else:
name_length = 0
name = name.strip()
data = ar.read(length - name_length)
# next block starts at even boundary
if length & 1:
ar.seek(1, os.SEEK_CUR)
return cls(name, modtime, owner, group, mode, data)
def ReadFile(path):
entries = []
with open(path) as ar:
if ar.read(8) != '!<arch>\n':
raise RuntimeError('%s is not an ar archive', path)
ar_size = os.stat(path).st_size
while ar.tell() < ar_size:
entries.append(ArEntry.decode(ar))
return entries