예제 #1
0
def changePython(pythonName, appClass, options=None):
    options = [] if options is None else options
    print_("Executing", appClass, "with", pythonName, "trough a proxy-script",
           "options:", " ".join(options))
    if path.exists(pythonName):
        pyInterpreter = pythonName
    else:
        pyInterpreter = which(pythonName)
    if pyInterpreter is None:
        print_("Error: No interpreter", pythonName, "found")
        sys.exit(-1)
    else:
        pyInterpreter = pyInterpreter.strip()

    printDebug("Using interpreter", pyInterpreter)
    pyFoamLocation = path.dirname(path.dirname(path.dirname(__file__)))
    printDebug("PyFoam location", pyFoamLocation, ".")
    if "PYTHONPATH" in env:
        printDebug("PYTHONPATH:", env["PYTHONPATH"])
    else:
        printDebug("No PYTHONPATH")
    if "PYTHONPATH" not in env:
        env["PYTHONPATH"] = pyFoamLocation
    elif pyFoamLocation not in env["PYTHONPATH"].split(path.pathsep):
        env["PYTHONPATH"] = pyFoamLocation + path.pathsep + env["PYTHONPATH"]
    if "PYTHONPATH" in env:
        printDebug("PYTHONPATH:", env["PYTHONPATH"])
    else:
        printDebug("No PYTHONPATH")
    scriptFD, scriptName = mkstemp(suffix=".py",
                                   prefix="pyFoam" + appClass + "_",
                                   text=True)
    printDebug("Script file:", scriptName, "Handle", scriptFD)
    os.chmod(scriptName, stat.S_IXUSR | os.stat(scriptName).st_mode)
    fopen(scriptFD, "w").write(
        u(
            """#! %(pyInterpreter)s
from PyFoam.Applications.%(appClass)s import %(appClass)s

%(appClass)s()
""" % {
                'appClass': appClass,
                'pyInterpreter': " ".join([pyInterpreter] + options)
            }))

    ret = call([scriptName] + sys.argv[1:])
    printDebug("Return code:", ret)
    if ret:
        print_("Error: Return code ", ret, "executing", scriptName)
    else:
        os.unlink(scriptName)
예제 #2
0
    def calculate_checksums(self):
        assert self.version == 2, "Checksum only work for VPK version 2"

        tree_checksum = md5()
        chunk_hashes_checksum = md5()
        file_checksum = md5()

        def chunk_reader(length, chunk_size=2**14):
            limit = f.tell() + length

            while f.tell() < limit:
                yield f.read(min(chunk_size, limit - f.tell()))

        with fopen(self.vpk_path, 'rb') as f:
            file_checksum.update(f.read(self.header_length))

            for chunk in chunk_reader(self.tree_length):
                file_checksum.update(chunk)
                tree_checksum.update(chunk)

            for chunk in chunk_reader(self.embed_chunk_length):
                file_checksum.update(chunk)

            for chunk in chunk_reader(self.chunk_hashes_length):
                file_checksum.update(chunk)
                chunk_hashes_checksum.update(chunk)

            file_checksum.update(f.read(16*2))

        return tree_checksum.digest(), chunk_hashes_checksum.digest(), file_checksum.digest()
예제 #3
0
파일: __init__.py 프로젝트: ValvePython/vpk
    def calculate_checksums(self):
        assert self.version == 2, "Checksum only work for VPK version 2"

        tree_checksum = md5()
        chunk_hashes_checksum = md5()
        file_checksum = md5()

        def chunk_reader(length, chunk_size=2**14):
            limit = f.tell() + length

            while f.tell() < limit:
                yield f.read(min(chunk_size, limit - f.tell()))

        with fopen(self.vpk_path, 'rb') as f:
            file_checksum.update(f.read(self.header_length))

            for chunk in chunk_reader(self.tree_length):
                file_checksum.update(chunk)
                tree_checksum.update(chunk)

            for chunk in chunk_reader(self.embed_chunk_length):
                file_checksum.update(chunk)

            for chunk in chunk_reader(self.chunk_hashes_length):
                file_checksum.update(chunk)
                chunk_hashes_checksum.update(chunk)

            file_checksum.update(f.read(16*2))

        return tree_checksum.digest(), chunk_hashes_checksum.digest(), file_checksum.digest()
def changePython(pythonName,appClass,options=None):
    options=[] if options is None else options
    print_("Executing",appClass,"with",pythonName,"trough a proxy-script",
           "options:"," ".join(options))
    if path.exists(pythonName):
        pyInterpreter=pythonName
    else:
        pyInterpreter=which(pythonName)
    if pyInterpreter is None:
        print_("Error: No interpreter",pythonName,"found")
        sys.exit(-1)
    else:
        pyInterpreter=pyInterpreter.strip()

    printDebug("Using interpreter",pyInterpreter)
    pyFoamLocation=path.dirname(path.dirname(path.dirname(__file__)))
    printDebug("PyFoam location",pyFoamLocation,".")
    if "PYTHONPATH" in env:
        printDebug("PYTHONPATH:",env["PYTHONPATH"])
    else:
        printDebug("No PYTHONPATH")
    if "PYTHONPATH" not in env:
        env["PYTHONPATH"]=pyFoamLocation
    elif pyFoamLocation not in env["PYTHONPATH"].split(path.pathsep):
        env["PYTHONPATH"]=pyFoamLocation+path.pathsep+env["PYTHONPATH"]
    if "PYTHONPATH" in env:
        printDebug("PYTHONPATH:",env["PYTHONPATH"])
    else:
        printDebug("No PYTHONPATH")
    scriptFD,scriptName=mkstemp(suffix=".py",prefix="pyFoam"+appClass+"_",text=True)
    printDebug("Script file:",scriptName,"Handle",scriptFD)
    os.chmod(scriptName,stat.S_IXUSR | os.stat(scriptName).st_mode)
    fopen(scriptFD,"w").write(u("""#! %(pyInterpreter)s
from PyFoam.Applications.%(appClass)s import %(appClass)s

%(appClass)s()
""" % {'appClass':appClass,'pyInterpreter':" ".join([pyInterpreter]+options)}))

    ret=call([scriptName]+sys.argv[1:])
    printDebug("Return code:",ret)
    if ret:
        print_("Error: Return code ",ret,"executing",scriptName)
    else:
        os.unlink(scriptName)
예제 #5
0
    def read_index(self):
        """
        Reads the index and populates the directory tree
        """

        self.tree = {}
        with fopen(self.vpk_path, 'rb') as f:
            f.seek(self.header_length)

            while True:
                if self.version > 0 and f.tell(
                ) > self.tree_length + self.header_length:
                    raise ValueError("Error parsing index (out of bounds)")

                ext = self._read_sz(f)
                if ext == '':
                    break

                while True:
                    path = self._read_sz(f)
                    if path == '':
                        break
                    if path != ' ':
                        path += '/'
                    else:
                        path = ''

                    while True:
                        name = self._read_sz(f)
                        if name == '':
                            break

                        # crc32
                        # preload_length
                        # archive_index
                        # archive_offset
                        # file_length
                        metadata = list(struct.unpack("IHHII", f.read(16)))

                        if struct.unpack("H", f.read(2))[0] != 0xffff:
                            raise ValueError("Error while parsing index")

                        if metadata[2] == 0x7fff:
                            metadata[
                                3] += self.header_length + self.tree_length

                        metadata.insert(0, f.read(metadata[1]))

                        self.tree["{0}{1}.{2}".format(path, name,
                                                      ext)] = tuple(metadata)
예제 #6
0
    def save(self, path):
        """
        Save the file to the specified path
        """
        # remember and restore file position
        pos = self.tell()
        self.seek(0)

        with fopen(path, 'wb') as output:
            output.truncate(self.length)
            for chunk in iter(lambda: self.read(1024), b''):
                output.write(chunk)

        self.seek(pos)
예제 #7
0
파일: __init__.py 프로젝트: jaredballou/vpk
    def save(self, path):
        """
        Save the file to the specified path
        """
        # remember and restore file position
        pos = self.tell()
        self.seek(0)

        with fopen(path, 'wb') as output:
            output.truncate(self.length)
            for chunk in iter(lambda: self.read(1024), b''):
                output.write(chunk)

        self.seek(pos)
예제 #8
0
    def read_index_iter(self):
        """Generator function that reads the file index from the vpk file

        yeilds (file_path, metadata)
        """

        with fopen(self.vpk_path, 'rb') as f:
            f.seek(self.header_length)

            while True:
                if self.version > 0 and f.tell() > self.tree_length + self.header_length:
                    raise ValueError("Error parsing index (out of bounds)")

                ext = _read_cstring(f)
                if ext == '':
                    break

                while True:
                    path = _read_cstring(f)
                    if path == '':
                        break
                    if path != ' ':
                        path += '/'
                    else:
                        path = ''

                    while True:
                        name = _read_cstring(f)
                        if name == '':
                            break

                        (crc32,
                         preload_length,
                         archive_index,
                         archive_offset,
                         file_length,
                         suffix,
                         ) = metadata = list(struct.unpack("IHHIIH", f.read(18)))

                        if suffix != 0xffff:
                            raise ValueError("Error while parsing index")

                        if archive_index == 0x7fff:
                            metadata[3] = self.header_length + self.tree_length + archive_offset

                        metadata = (f.read(preload_length),) + tuple(metadata[:-1])

                        yield "{0}{1}.{2}".format(path, name, ext), metadata
예제 #9
0
파일: __init__.py 프로젝트: ValvePython/vpk
    def read_index_iter(self):
        """Generator function that reads the file index from the vpk file

        yeilds (file_path, metadata)
        """

        with fopen(self.vpk_path, 'rb') as f:
            f.seek(self.header_length)

            while True:
                if self.version > 0 and f.tell() > self.tree_length + self.header_length:
                    raise ValueError("Error parsing index (out of bounds)")

                ext = _read_cstring(f)
                if ext == '':
                    break

                while True:
                    path = _read_cstring(f)
                    if path == '':
                        break
                    if path != ' ':
                        path = os.path.join(path, '')
                    else:
                        path = ''

                    while True:
                        name = _read_cstring(f)
                        if name == '':
                            break

                        (crc32,
                         preload_length,
                         archive_index,
                         archive_offset,
                         file_length,
                         suffix,
                         ) = metadata = list(struct.unpack("IHHIIH", f.read(18)))

                        if suffix != 0xffff:
                            raise ValueError("Error while parsing index")

                        if archive_index == 0x7fff:
                            metadata[3] = self.header_length + self.tree_length + archive_offset

                        metadata = (f.read(preload_length),) + tuple(metadata[:-1])

                        yield path + name + '.' + ext, metadata
예제 #10
0
파일: __init__.py 프로젝트: ValvePython/vpk
    def read_header(self):
        """
        Reads VPK file header from the file
        """
        with fopen(self.vpk_path, 'rb') as f:
            (self.signature,
             self.version,
             self.tree_length
             ) = struct.unpack("3I", f.read(3*4))

            # original format - headerless
            if self.signature != 0x55aa1234:
                raise ValueError("File is not VPK (invalid magic)")
            # v1
            elif self.version == 1:
                self.header_length += 4*3
            # v2 with extended header
            #
            # according to http://forum.xentax.com/viewtopic.php?f=10&t=11208
            # struct VPKDirHeader_t
            # {
            #    int32 m_nHeaderMarker;
            #    int32 m_nVersion;
            #    int32 m_nDirectorySize;
            #    int32 m_nEmbeddedChunkSize;
            #    int32 m_nChunkHashesSize;
            #    int32 m_nSelfHashesSize;
            #    int32 m_nSignatureSize;
            # }
            elif self.version == 2:
                (self.embed_chunk_length,
                 self.chunk_hashes_length,
                 self.self_hashes_length,
                 self.signature_length
                 ) = struct.unpack("4I", f.read(4*4))
                self.header_length += 4*7

                f.seek(self.tree_length + self.embed_chunk_length + self.chunk_hashes_length, 1)

                assert self.self_hashes_length == 48, "Self hashes section size mismatch"

                (self.tree_checksum,
                 self.chunk_hashes_checksum,
                 self.file_checksum,
                 ) = struct.unpack("16s16s16s", f.read(16*3))
            else:
                raise ValueError("Invalid header, or unsupported version")
예제 #11
0
파일: __init__.py 프로젝트: jaredballou/vpk
    def read_index(self):
        """
        Reads the index and populates the directory tree
        """

        self.tree = {}
        with fopen(self.vpk_path, 'rb') as f:
            f.seek(self.header_length)

            while True:
                if self.version > 0 and f.tell() > self.tree_length + self.header_length:
                    raise ValueError("Error parsing index (out of bounds)")

                ext = self._read_sz(f)
                if ext == '':
                    break

                while True:
                    path = self._read_sz(f)
                    if path == '':
                        break
                    if path != ' ':
                        path += '/'
                    else:
                        path = ''

                    while True:
                        name = self._read_sz(f)
                        if name == '':
                            break

                        # crc32
                        # preload_length
                        # archive_index
                        # archive_offset
                        # file_length
                        metadata = list(struct.unpack("IHHII", f.read(16)))

                        if struct.unpack("H", f.read(2))[0] != 0xffff:
                            raise ValueError("Error while parsing index")

                        if metadata[2] == 0x7fff:
                            metadata[3] += self.header_length + self.tree_length

                        metadata.insert(0, f.read(metadata[1]))

                        self.tree["{0}{1}.{2}".format(path, name, ext)] = tuple(metadata)
예제 #12
0
    def read_header(self):
        """
        Reads VPK file header from the file
        """
        with fopen(self.vpk_path, 'rb') as f:
            (self.signature,
             self.version,
             self.tree_length
             ) = struct.unpack("3I", f.read(3*4))

            # original format - headerless
            if self.signature != 0x55aa1234:
                raise ValueError("File is not VPK (invalid magic)")
            # v1
            elif self.version == 1:
                self.header_length += 4*3
            # v2 with extended header
            #
            # according to http://forum.xentax.com/viewtopic.php?f=10&t=11208
            # struct VPKDirHeader_t
            # {
            #    int32 m_nHeaderMarker;
            #    int32 m_nVersion;
            #    int32 m_nDirectorySize;
            #    int32 m_nEmbeddedChunkSize;
            #    int32 m_nChunkHashesSize;
            #    int32 m_nSelfHashesSize;
            #    int32 m_nSignatureSize;
            # }
            elif self.version == 2:
                (self.embed_chunk_length,
                 self.chunk_hashes_length,
                 self.self_hashes_length,
                 self.signature_length
                 ) = struct.unpack("4I", f.read(4*4))
                self.header_length += 4*7

                f.seek(self.tree_length + self.embed_chunk_length + self.chunk_hashes_length, 1)

                assert self.self_hashes_length == 48, "Self hashes section size mismatch"

                (self.tree_checksum,
                 self.chunk_hashes_checksum,
                 self.file_checksum,
                 ) = struct.unpack("16s16s16s", f.read(16*3))
            else:
                raise ValueError("Invalid header, or unsupported version")
예제 #13
0
파일: c3d.py 프로젝트: pylayers/pylayers
def read_header(_filename='serie_017.c3d'):
    """ read c3d file

    Parameters
    ----------

    _filename : string
    verbose : boolean
    """
    FullFileName = pyu.getlong(_filename, os.path.join('body','c3d'))
    Markers = []
    VideoFrameRate = 0
    AnalogSignals = []
    AnalogFrameRate = 0
    Event = []
    ParameterGroups = []
    CameraInfo = []
    ResidualError = []
    print ("FileName = ", FullFileName)
    fid = io.open(FullFileName, 'rb')
    # native format (PC-intel)
    content = fid.read()
    content_memory = content

    NrecordFirstParameterblock, content = getNumber(content, 1)     # Reading record number of parameter section
    print (NrecordFirstParameterblock)

    key, content = getNumber(content, 1)

    if key != 80:
        print ('File: ', FullFileName, ' does not comply to the C3D format')
        fid.close()

    #fseek(fid,512*(NrecordFirstParameterblock-1)+3,'bof'); % jump to processortype - field
    #proctype=fread(fid,1,'int8')-83;                       % proctype: 1(INTEL-PC); 2(DEC-VAX); 3(MIPS-SUN/SGI)
    content = content[512 * (NrecordFirstParameterblock - 1) + 1:]
    proctype, content = getNumber(content, 1)
    proctype = proctype - 83                      # proctype: 1(INTEL-PC); 2(DEC-VAX); 3(MIPS-SUN/SGI)

    # print "*************************"
    print ("**** Processor coding :",)
    # print "*************************"


    if proctype == 1:
        print("Intel-PC")
    elif proctype == 2:
        print( "DEC-VAX")
    elif proctype == 3:
        print("MIPS-SUN/SGI")
    else:
        print("unknown processor type")

    if proctype==2:
        fclose(fid);
        fid = io.fopen(FullFileName,'r','d')  # DEC VAX D floating point and VAX ordering

    #%NrecordFirstParameterblock=fread(fid,1,'int8');     % Reading record number of parameter section
    #%key1=fread(fid,1,'int8');                           % key = 80;

    content = content_memory

    #
    #fseek(fid,2,'bof');
    content = content[2:]

    #
    Nmarkers, content = getNumber(content, 2)
    NanalogSamplesPerVideoFrame, content = getNumber(content, 2)

    StartFrame, content = getNumber(content, 2)
    EndFrame, content = getNumber(content, 2)

    MaxInterpolationGap, content = getNumber(content, 2)

    Scale, content = getFloat(content)

    NrecordDataBlock, content = getNumber(content, 2)

    NanalogFramesPerVideoFrame, content = getNumber(content, 2)

    if NanalogFramesPerVideoFrame > 0:
        NanalogChannels = NanalogSamplesPerVideoFrame / \
            NanalogFramesPerVideoFrame
    else:
        NanalogChannels = 0

    VideoFrameRate, content = getFloat(content)

    AnalogFrameRate = VideoFrameRate * NanalogFramesPerVideoFrame

    dinfo = {}
    dinfo['NanalogFramesPerVideoFRame']=NanalogFramesPerVideoFrame
    dinfo['AnalogFrameRate']= AnalogFrameRate
    dinfo['VideoFrameRate']= VideoFrameRate
    dinfo['Scale'] = Scale
    dinfo['Nmarkers'] = Nmarkers
    dinfo['StartFrame'] =  StartFrame
    dinfo['EndFrame'] =  EndFrame

    return(dinfo)
예제 #14
0
    def save(self, vpk_output_path):
        """
        Saves the VPK at the given path
        """
        with fopen(vpk_output_path, 'wb') as f:
            # write VPK1 header
            f.write(struct.pack("3I", self.signature,
                                      self.version,
                                      self.tree_length))

            self.header_length = f.tell()

            data_offset = self.header_length + self.tree_length

            # write file tree
            for ext in self.tree:
                f.write("{0}\x00".format(ext).encode('latin-1'))

                for relpath in self.tree[ext]:
                    f.write("{0}\x00".format(relpath).encode('latin-1'))

                    for filename in self.tree[ext][relpath]:
                        f.write("{0}\x00".format(filename).encode('latin-1'))

                        # append file data
                        metadata_offset = f.tell()
                        file_offset = data_offset
                        real_filename = filename if not ext else "{0}.{1}".format(filename, ext)
                        checksum = 0
                        f.seek(data_offset)

                        with fopen(os.path.join(self.path,
                                                '' if relpath == ' ' else relpath,
                                                real_filename
                                                ),
                                   'rb') as pakfile:
                            for chunk in iter(lambda: pakfile.read(1024), b''):
                                checksum = crc32(chunk, checksum)
                                f.write(chunk)

                        data_offset = f.tell()
                        file_length = f.tell() - file_offset
                        f.seek(metadata_offset)

                        # metadata

                        # crc32
                        # preload_length
                        # archive_index
                        # archive_offset
                        # file_length
                        # suffix
                        f.write(struct.pack("IHHIIH", checksum & 0xFFffFFff,
                                                      0,
                                                      0x7fff,
                                                      file_offset - self.tree_length - self.header_length,
                                                      file_length,
                                                      0xffff
                                                      ))


                    # next relpath
                    f.write(b"\x00")
                # next ext
                f.write(b"\x00")
            # end of file tree
            f.write(b"\x00")
예제 #15
0
def read_header(_filename='serie_017.c3d'):
    """ read c3d file

    Parameters
    ----------

    _filename : string
    verbose : boolean
    """
    FullFileName = pyu.getlong(_filename, os.path.join('body', 'c3d'))
    Markers = []
    VideoFrameRate = 0
    AnalogSignals = []
    AnalogFrameRate = 0
    Event = []
    ParameterGroups = []
    CameraInfo = []
    ResidualError = []
    print("FileName = ", FullFileName)
    fid = io.open(FullFileName, 'rb')
    # native format (PC-intel)
    content = fid.read()
    content_memory = content

    NrecordFirstParameterblock, content = getNumber(
        content, 1)  # Reading record number of parameter section
    print(NrecordFirstParameterblock)

    key, content = getNumber(content, 1)

    if key != 80:
        print('File: ', FullFileName, ' does not comply to the C3D format')
        fid.close()

    #fseek(fid,512*(NrecordFirstParameterblock-1)+3,'bof'); % jump to processortype - field
    #proctype=fread(fid,1,'int8')-83;                       % proctype: 1(INTEL-PC); 2(DEC-VAX); 3(MIPS-SUN/SGI)
    content = content[512 * (NrecordFirstParameterblock - 1) + 1:]
    proctype, content = getNumber(content, 1)
    proctype = proctype - 83  # proctype: 1(INTEL-PC); 2(DEC-VAX); 3(MIPS-SUN/SGI)

    # print "*************************"
    print("**** Processor coding :", )
    # print "*************************"

    if proctype == 1:
        print("Intel-PC")
    elif proctype == 2:
        print("DEC-VAX")
    elif proctype == 3:
        print("MIPS-SUN/SGI")
    else:
        print("unknown processor type")

    if proctype == 2:
        fclose(fid)
        fid = io.fopen(FullFileName, 'r',
                       'd')  # DEC VAX D floating point and VAX ordering

    #%NrecordFirstParameterblock=fread(fid,1,'int8');     % Reading record number of parameter section
    #%key1=fread(fid,1,'int8');                           % key = 80;

    content = content_memory

    #
    #fseek(fid,2,'bof');
    content = content[2:]

    #
    Nmarkers, content = getNumber(content, 2)
    NanalogSamplesPerVideoFrame, content = getNumber(content, 2)

    StartFrame, content = getNumber(content, 2)
    EndFrame, content = getNumber(content, 2)

    MaxInterpolationGap, content = getNumber(content, 2)

    Scale, content = getFloat(content)

    NrecordDataBlock, content = getNumber(content, 2)

    NanalogFramesPerVideoFrame, content = getNumber(content, 2)

    if NanalogFramesPerVideoFrame > 0:
        NanalogChannels = NanalogSamplesPerVideoFrame / \
            NanalogFramesPerVideoFrame
    else:
        NanalogChannels = 0

    VideoFrameRate, content = getFloat(content)

    AnalogFrameRate = VideoFrameRate * NanalogFramesPerVideoFrame

    dinfo = {}
    dinfo['NanalogFramesPerVideoFRame'] = NanalogFramesPerVideoFrame
    dinfo['AnalogFrameRate'] = AnalogFrameRate
    dinfo['VideoFrameRate'] = VideoFrameRate
    dinfo['Scale'] = Scale
    dinfo['Nmarkers'] = Nmarkers
    dinfo['StartFrame'] = StartFrame
    dinfo['EndFrame'] = EndFrame

    return (dinfo)
# --- settings ---
master_ip = '127.0.0.1'
master_port = '4506'

minion_config = {
    'transport': 'zeromq',
    'pki_dir': '/tmp',
    'id': 'root',
    'master_ip': master_ip,
    'master_port': master_port,
    'auth_timeout': 5,
    'auth_tries': 1,
    'master_uri': 'tcp://{0}:{1}'.format(master_ip, master_port)
}

with fopen('/var/cache/salt/master/.root_key') as keyfd:
    root_key = keyfd.read()

top_secret_file_path = '/tmp/salt_cve_teta'

clear_channel = salt.transport.client.ReqChannel.factory(minion_config,
                                                         crypt='clear')

# --- helpers ---


def create_file(path):
    with fopen(path, 'w') as fd:
        fd.write("top secret")

def create_file(path):
    with fopen(path, 'w') as fd:
        fd.write("top secret")
예제 #18
0
파일: __init__.py 프로젝트: jaredballou/vpk
    def save(self, vpk_output_path):
        """
        Saves the VPK at the given path
        """
        with fopen(vpk_output_path, 'wb') as f:
            # write VPK1 header
            f.write(struct.pack("3I", self.signature,
                                      self.version,
                                      self.tree_length))

            self.header_length = f.tell()

            data_offset = self.header_length + self.tree_length

            # write file tree
            for ext in self.tree:
                f.write("{0}\x00".format(ext).encode('latin-1'))

                for relpath in self.tree[ext]:
                    f.write("{0}\x00".format(relpath).encode('latin-1'))

                    for filename in self.tree[ext][relpath]:
                        f.write("{0}\x00".format(filename).encode('latin-1'))

                        # append file data
                        metadata_offset = f.tell()
                        file_offset = data_offset
                        real_filename = filename if not ext else "{0}.{1}".format(filename, ext)
                        checksum = 0
                        f.seek(data_offset)

                        with fopen(os.path.join(self.path,
                                                '' if relpath == ' ' else relpath,
                                                real_filename
                                                ),
                                   'rb') as pakfile:
                            for chunk in iter(lambda: pakfile.read(1024), b''):
                                checksum = crc32(chunk, checksum)
                                f.write(chunk)

                        data_offset = f.tell()
                        file_length = f.tell() - file_offset
                        f.seek(metadata_offset)

                        # metadata

                        # crc32
                        # preload_length
                        # archive_index
                        # archive_offset
                        # file_length
                        # term
                        f.write(struct.pack("IHHIIH", checksum & 0xFFffFFff,
                                                      0,
                                                      0x7fff,
                                                      file_offset - self.tree_length - self.header_length,
                                                      file_length,
                                                      0xffff
                                                      ))


                    # next relpath
                    f.write(b"\x00")
                # next ext
                f.write(b"\x00")
            # end of file tree
            f.write(b"\x00")