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:
12
tools/lsar.py
Executable file
12
tools/lsar.py
Executable 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
48
tools/objtools/ar.py
Normal 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
|
||||
Reference in New Issue
Block a user