diff options
Diffstat (limited to 'lib/portage/binpkg.py')
-rw-r--r-- | lib/portage/binpkg.py | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/portage/binpkg.py b/lib/portage/binpkg.py new file mode 100644 index 000000000..a48e09bdb --- /dev/null +++ b/lib/portage/binpkg.py @@ -0,0 +1,76 @@ +# Copyright 2001-2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +import tarfile +from portage import os +from portage.const import SUPPORTED_XPAK_EXTENSIONS, SUPPORTED_GPKG_EXTENSIONS +from portage.exception import InvalidBinaryPackageFormat +from portage.output import colorize +from portage.util import writemsg + + +def get_binpkg_format(binpkg_path, check_file=False, remote=False): + if binpkg_path.endswith(SUPPORTED_XPAK_EXTENSIONS): + file_ext_format = "xpak" + elif binpkg_path.endswith(SUPPORTED_GPKG_EXTENSIONS): + file_ext_format = "gpkg" + else: + file_ext_format = None + + if remote: + if file_ext_format is not None: + return file_ext_format + else: + raise InvalidBinaryPackageFormat( + f"Unsupported binary package format from '{binpkg_path}'" + ) + + if file_ext_format is not None and not check_file: + return file_ext_format + + try: + with open(binpkg_path, "rb") as binpkg_file: + header = binpkg_file.read(100) + if b"/gpkg-1\x00" in header: + file_format = "gpkg" + else: + binpkg_file.seek(-16, 2) + tail = binpkg_file.read(16) + if (tail[0:8] == b"XPAKSTOP") and (tail[12:16] == b"STOP"): + file_format = "xpak" + else: + file_format = None + + # check if wrong order gpkg + if file_format is None: + try: + with tarfile.open(binpkg_path) as gpkg_tar: + if "gpkg-1" in (os.path.basename(f) for f in gpkg_tar.getnames()): + file_format = "gpkg" + except tarfile.TarError: + pass + + except Exception as err: + # We got many different exceptions here, so have to catch all of them. + file_format = None + writemsg( + colorize("ERR", f"Error reading binpkg '{binpkg_path}': {err}\n"), + ) + raise InvalidBinaryPackageFormat(f"Error reading binpkg '{binpkg_path}': {err}") + + if file_format is None: + raise InvalidBinaryPackageFormat( + f"Unsupported binary package format from '{binpkg_path}'" + ) + + if (file_ext_format is not None) and (file_ext_format != file_format): + writemsg( + colorize( + "WARN", + "File {} binpkg format mismatch, actual format: {}\n".format( + binpkg_path, file_format + ), + ) + ) + + return file_format |