diff options
-rwxr-xr-x | images/add_adb_root/add_adb_root.py | 60 |
1 files changed, 52 insertions, 8 deletions
diff --git a/images/add_adb_root/add_adb_root.py b/images/add_adb_root/add_adb_root.py index 8dc6d34..4063576 100755 --- a/images/add_adb_root/add_adb_root.py +++ b/images/add_adb_root/add_adb_root.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. import enum +import magic import os import re import sh @@ -30,6 +31,7 @@ class ImageType(enum.Enum): class CompressionType(enum.Enum): none = 0 gz = 1 + xz = 2 class Bootimage(object): def __init__(self, path): @@ -39,7 +41,9 @@ class Bootimage(object): self._tmpdir = tempfile.mkdtemp() self._kernel = self._tmpdir + os.sep + "kernel.img" - self._ramdisk = self._tmpdir + os.sep + "ramdisk.cpio.gz" + # We don't know yet the compression type of the ramdisk so we use + # a generic .img instead of a specific extension like .gz or .xz + self._ramdisk = self._tmpdir + os.sep + "ramdisk.cpio.img" self._config = self._tmpdir + os.sep + "bootimg.cfg" def _get_metadata(self): @@ -98,8 +102,8 @@ class Bootimage(object): def add_adb_root(self, output_file_path): self.extract() - self._ramdisk = Ramdisk(self._ramdisk, - CompressionType.gz).add_adb_root() + compression = identify_compression_type(self._ramdisk) + self._ramdisk = Ramdisk(self._ramdisk, compression).add_adb_root() self.recreate(output_file_path) return output_file_path @@ -208,14 +212,39 @@ class Ramdisk(object): def compress(self): if self._compression_type is not CompressionType.none: - sh.gzip("--no-name", self._path) - self._path = self._path + ".gz" + if self._compression_type == CompressionType.gz: + sh.gzip("--no-name", self._path) + self._path = self._path + ".gz" + elif self._compression_type == CompressionType.xz: + # TODO: also support other architectures than ARM + # See scripts/xz_wrap.sh in Linux source code for more details + sh.xz("--check=crc32", "--arm", "--lzma2=dict=32M", self._path) + self._path = self._path + ".xz" + return self._path def uncompress(self): - if self._compression_type is not CompressionType.none: - sh.gunzip(self._path) - self._path = re.sub("\.gz$", "", self._path) + # The path looks like that: [...]/ramdisk.cpio.img. The .img is there + # because we needed to extract the file before finding out how it was + # compressed or if it was not compressed. + new_path = None + if self._compression_type == CompressionType.none: + new_path = re.sub("\.img$", "", self._path) + elif self._compression_type == CompressionType.gz: + new_path = re.sub("\.img$", ".gz", self._path) + elif self._compression_type == CompressionType.xz: + new_path = re.sub("\.img$", ".xz", self._path) + + os.rename(self._path, new_path) + self._path = new_path + + if self._compression_type == CompressionType.gz: + sh.gunzip(self._path) + self._path = re.sub("\.gz$", "", self._path) + elif self._compression_type == CompressionType.xz: + sh.unxz(self._path) + self._path = re.sub("\.xz$", "", self._path) + return self._path def add_adb_root(self): @@ -237,6 +266,21 @@ def usage(progname): progname)) sys.exit(1) +def identify_compression_type(path): + m = magic.detect_from_filename(path) + if not m: + print("/!\ MIME type not found for {}".format(path)) + sys.exit(1) + mime_type = m.mime_type + if mime_type == 'application/gzip': + return CompressionType.gz + elif mime_type == 'application/x-xz': + return CompressionType.xz + else: + print("/!\ TODO: MIME type {} (of file {}) is not implemented".format( + m.mime_type, path)) + sys.exit(1) + def identify_image_type(path): try: output = sh.abootimg("-i", path) |