aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/portage/binpkg.py')
-rw-r--r--lib/portage/binpkg.py76
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