aboutsummaryrefslogtreecommitdiff
blob: a48e09bdb8d1c17987bdc4585d536e10a72c2e15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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