mirror of
https://git.yoctoproject.org/git/opkg-utils
synced 2026-01-18 04:02:06 +01:00
This patch fixes common linter warnings. Signed-off-by: Robert Lehmann <robert.lehmann@sitec-systems.de> Signed-off-by: Alex Stewart <astewart.49c6@gmail.com>
146 lines
4.1 KiB
Python
146 lines
4.1 KiB
Python
# SPDX-License-Identifier: GPL-2.0-only
|
|
"""
|
|
arfile - A module to parse GNU ar archives.
|
|
|
|
Copyright (c) 2006-7 Paul Sokolovsky
|
|
This file is released under the terms
|
|
of GNU General Public License v2 or later.
|
|
"""
|
|
from __future__ import absolute_import
|
|
from __future__ import print_function
|
|
import sys
|
|
import os
|
|
import tarfile
|
|
|
|
|
|
class FileSection(object):
|
|
"A class which allows to treat portion of file as separate file object."
|
|
|
|
def __init__(self, f, offset, size):
|
|
self.f = f
|
|
self.offset = offset
|
|
self.size = size
|
|
self.seek(0, 0)
|
|
|
|
def seek(self, offset, whence=0):
|
|
if whence == 0:
|
|
return self.f.seek(offset + self.offset, whence)
|
|
elif whence == 1:
|
|
return self.f.seek(offset, whence)
|
|
elif whence == 2:
|
|
return self.f.seek(self.offset + self.size + offset, 0)
|
|
else:
|
|
assert False
|
|
|
|
def seekable(self):
|
|
return True
|
|
|
|
def tell(self):
|
|
return self.f.tell() - self.offset
|
|
|
|
def read(self, size=-1):
|
|
return self.f.read(size)
|
|
|
|
|
|
class ArFile(object):
|
|
|
|
def __init__(self, f, fn):
|
|
self.f = f
|
|
self.directory = {}
|
|
self.directoryRead = False
|
|
|
|
signature = self.f.readline()
|
|
assert signature == "!<arch>\n" or signature == b"!<arch>\n", "Old ipk format (non-deb) is unsupported, file: %s, magic: %s, expected %s" % (fn, signature, "!<arch>")
|
|
self.directoryOffset = self.f.tell()
|
|
|
|
def open(self, fname):
|
|
if fname in self.directory:
|
|
return FileSection(self.f, self.directory[fname][-1], int(self.directory[fname][5]))
|
|
|
|
if self.directoryRead:
|
|
raise IOError("AR member not found: " + fname)
|
|
|
|
f = self._scan(fname)
|
|
if f is None:
|
|
raise IOError("AR member not found: " + fname)
|
|
return f
|
|
|
|
def _scan(self, fname):
|
|
self.f.seek(self.directoryOffset, 0)
|
|
|
|
while True:
|
|
line = self.f.readline()
|
|
if not line:
|
|
self.directoryRead = True
|
|
return None
|
|
|
|
if line.decode('ascii') == "\n":
|
|
line = self.f.readline()
|
|
if not line:
|
|
break
|
|
line = line.decode('ascii')
|
|
line = line.replace('`', '')
|
|
# Field lengths from /usr/include/ar.h:
|
|
ar_field_lens = [16, 12, 6, 6, 8, 10, 2]
|
|
descriptor = []
|
|
for field_len in ar_field_lens:
|
|
descriptor.append(line[:field_len].strip())
|
|
line = line[field_len:]
|
|
size = int(descriptor[5])
|
|
# Check for optional / terminator
|
|
if descriptor[0][-1] == "/":
|
|
memberName = descriptor[0][:-1]
|
|
else:
|
|
memberName = descriptor[0]
|
|
self.directory[memberName] = descriptor + [self.f.tell()]
|
|
|
|
if memberName == fname:
|
|
# Record directory offset to start from next time
|
|
self.directoryOffset = self.f.tell() + size
|
|
return FileSection(self.f, self.f.tell(), size)
|
|
|
|
# Skip data and loop
|
|
if size % 2:
|
|
size = size + 1
|
|
data = self.f.seek(size, 1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if None:
|
|
fn = sys.argv[1]
|
|
f = open(fn, "rb")
|
|
|
|
ar = ArFile(f, fn)
|
|
tarStream = ar.open("data.tar.gz")
|
|
print("--------")
|
|
tarStream = ar.open("data.tar.gz")
|
|
print("--------")
|
|
tarStream = ar.open("control.tar.gz")
|
|
print("--------")
|
|
tarStream = ar.open("control.tar.gz2")
|
|
|
|
sys.exit(0)
|
|
|
|
dir = "."
|
|
|
|
if len(sys.argv) > 1:
|
|
dir = sys.argv[1]
|
|
|
|
for f in os.listdir(dir):
|
|
if not f.endswith(".opk") and not f.endswith(".ipk"):
|
|
continue
|
|
|
|
print("=== %s ===" % f)
|
|
fn = "%s/%s" % (dir, f)
|
|
f = open(fn, "rb")
|
|
|
|
ar = ArFile(f, fn)
|
|
tarStream = ar.open("control.tar.gz")
|
|
tarf = tarfile.open("control.tar.gz", "r", tarStream)
|
|
|
|
try:
|
|
f2 = tarf.extractfile("control")
|
|
except KeyError:
|
|
f2 = tarf.extractfile("./control")
|
|
print(f2.read())
|