Ejemplo n.º 1
0
    def _create_header(info, format_, encoding, errors):
        """Return a header block. info is a dictionary with file
           information, format must be one of the *_FORMAT constants.
        """
        parts = [
            tarfile.stn(info.get("name", ""), 100, encoding, errors),
            tarfile.itn(info.get("mode", 0), 8, format_),
            tarfile.itn(info.get("uid", 0), 8, format_),
            tarfile.itn(info.get("gid", 0), 8, format_),
            tarfile.itn(info.get("size", 0), 12, format_),
            tarfile.itn(info.get("mtime", 0), 12, format_),
            b" " * 8,  # checksum field
            info.get("type", tarfile.REGTYPE),
            tarfile.stn(info.get("linkname", ""), 100, encoding, errors),
            info.get("magic", tarfile.POSIX_MAGIC),
            tarfile.stn(info.get("uname", ""), 32, encoding, errors),
            tarfile.stn(info.get("gname", ""), 32, encoding, errors),
            tarfile.itn(info.get("devmajor", 0), 8, format_),
            tarfile.itn(info.get("devminor", 0), 8, format_),
            tarfile.stn(info.get("prefix", ""), 155, encoding, errors)
        ]

        buf = struct.pack("%ds" % tarfile.BLOCKSIZE, b"".join(parts))
        chksum = tarfile.calc_chksums(buf[-tarfile.BLOCKSIZE:])[0]
        buf = buf[:-364] + bytes("%06o\0" % chksum, "ascii") + buf[-357:]
        return buf
Ejemplo n.º 2
0
    def parse_tar_header_simple(header_data):
        header = {
            'size':
            tarfile.nti(header_data[size_offset:size_offset + size_len]),
            'chksum':
            tarfile.nti(header_data[checksum_offset:checksum_offset +
                                    checksum_len])
        }

        if header['chksum'] not in tarfile.calc_chksums(header_data):
            raise tarfile.InvalidHeaderError("chksum not match")
        return header
Ejemplo n.º 3
0
Archivo: build.py Proyecto: nuta/resea
def main():
    parser = argparse.ArgumentParser(description="The MinLin distro build system.")
    parser.add_argument("--build-dir", help="The build directory.", required=True)
    parser.add_argument("-o", dest="outfile", required=True)
    args = parser.parse_args()

    root_dir = Path(args.build_dir)
    shutil.rmtree(root_dir, ignore_errors=True)
    os.makedirs(root_dir, exist_ok=True)

    packages = get_packages()
    for pkg in packages.values():
        pkg.build()
        build_package(root_dir, pkg)

    tar = tarfile.open(args.outfile, "w")
    tar.add(root_dir, "/", recursive=True)
    tar.close()

    # Add symlinks.
    tar_data = bytes()
    for src, dst in all_symlinks.items():
        src = src.lstrip("/")
        dst = dst.lstrip("/")
        fmt = f"100s{8+8+8}x12s12s8sc100s8s{32+32+8+8+155+12}x"
        magic  = b"ustar  \x00"
        size = b"00000000000\0"
        time_modified = b"00000000000\0"
        type_ = b"2" # symbolic link
        header = struct.pack(fmt, src.encode("ascii"), size, time_modified,
            b"", type_, dst.encode("ascii"), magic)

        from tarfile import calc_chksums
        checksum = bytes("%06o\0" % calc_chksums(header)[0], "ascii")
        header = struct.pack(fmt, src.encode("ascii"), size, time_modified,
            checksum, type_, dst.encode("ascii"), magic)
        tar_data += header

    tar_data += open(args.outfile, "rb").read()
    open(args.outfile, "wb").write(tar_data)
Ejemplo n.º 4
0
    def parse_tar_header(header_data):
        header = dict()
        tar_header = struct.unpack(
            '=100s8s8s8s12s12s8sc100s6s2s32s32s8s8s155s12x', header_data)
        header['name'] = tar_header[0]
        header['mode'] = tar_header[1]
        header['uid'] = tar_header[2]
        header['gid'] = tar_header[3]
        header['size'] = tarfile.nti(tar_header[4])
        header['mtime'] = tar_header[5]
        header['chksum'] = tarfile.nti(tar_header[6])
        header['typeflag'] = tar_header[7]
        header['linkname'] = tar_header[8]
        header['magic'] = tar_header[9]
        header['version'] = tar_header[10]
        header['uname'] = tar_header[11]
        header['gname'] = tar_header[12]
        header['devmajor'] = tar_header[13]
        header['devminor'] = tar_header[14]
        header['prefix'] = tar_header[15]

        if header['chksum'] not in tarfile.calc_chksums(header_data):
            raise tarfile.InvalidHeaderError("chksum not match")
        return header
Ejemplo n.º 5
0
                        def write_archivefile(data):
                            # Intercept writes to the archive file and rewrite any headers matching our criteria
                            for block_idx in range(
                                (len(data) + tarfile.BLOCKSIZE - 1) //
                                    tarfile.BLOCKSIZE):
                                block = data[block_idx *
                                             tarfile.BLOCKSIZE:(block_idx +
                                                                1) *
                                             tarfile.BLOCKSIZE]
                                cur_offset = archive_props["offset"]
                                archive_props["offset"] += len(block)

                                if cur_offset != archive_props[
                                        "next_header_offset"]:
                                    continue

                                try:
                                    tarinfo = out_archive.tarinfo.frombuf(
                                        block, out_archive.encoding,
                                        out_archive.errors)
                                except tarfile.EOFHeaderError:  # type: ignore[attr-defined]
                                    break

                                block_count = (tarinfo.size + tarfile.BLOCKSIZE
                                               - 1) // tarfile.BLOCKSIZE
                                archive_props[
                                    "next_header_offset"] = archive_props[
                                        "offset"] + block_count * tarfile.BLOCKSIZE

                                if tarinfo.devmajor != 0 or tarinfo.devmajor != 0 or tarinfo.type in (
                                        tarfile.CHRTYPE, tarfile.BLKTYPE):
                                    continue

                                # Erase major/minor fields for non-device files as other tar-archive producing tools do.
                                if not isinstance(data, bytearray):
                                    data = bytearray(data)

                                DEVNUMBERS_OFFSET = 329
                                DEVNUMBERS_LENGTH = 2 * 8
                                DEVNUMBERS_RANGE = slice(
                                    block_idx * tarfile.BLOCKSIZE +
                                    DEVNUMBERS_OFFSET,
                                    block_idx * tarfile.BLOCKSIZE +
                                    DEVNUMBERS_OFFSET + DEVNUMBERS_LENGTH,
                                )
                                CHECKSUM_OFFSET = 148
                                CHECKSUM_LENGTH = 8
                                CHECKSUM_RANGE = slice(
                                    block_idx * tarfile.BLOCKSIZE +
                                    CHECKSUM_OFFSET,
                                    block_idx * tarfile.BLOCKSIZE +
                                    CHECKSUM_OFFSET + CHECKSUM_LENGTH,
                                )

                                data[
                                    DEVNUMBERS_RANGE] = b"\0" * DEVNUMBERS_LENGTH

                                # Recompute checksum, but whipe checksum field (with spaces) before doing so
                                data[CHECKSUM_RANGE] = b" " * CHECKSUM_LENGTH
                                chksum, *_ = tarfile.calc_chksums(  # type: ignore[attr-defined]
                                    data[block_idx *
                                         tarfile.BLOCKSIZE:(block_idx + 1) *
                                         tarfile.BLOCKSIZE])
                                data[CHECKSUM_RANGE] = b"%06o\0 " % (chksum, )

                            return original_write(data)
Ejemplo n.º 6
0
 def update_event(self, inp=-1):
     self.set_output_val(0, tarfile.calc_chksums(self.input(0)))