Skip to content

cramfs.py

ofrak.core.cramfs

Cramfs (GenericBinary, FilesystemRoot) dataclass

Filesystem stored in CramFS format.

CramfsPacker (Packer)

Compress and package files into a Linux Compressed ROM File System.

pack(self, resource, config=None) async

Pack the given resource.

Users should not call this method directly; rather, they should run Resource.run or Resource.pack.

Parameters:

Name Type Description Default
resource Resource required
config

Optional config for packing. If an implementation provides a default, this default will always be used when config would otherwise be None. Note that a copy of the default config will be passed, so the default config values cannot be modified persistently by a component run.

None
Source code in ofrak/core/cramfs.py
async def pack(self, resource: Resource, config=None):
    cramfs_view: Cramfs = await resource.view_as(Cramfs)
    temp_flush_dir = await cramfs_view.flush_to_disk()
    with tempfile.NamedTemporaryFile(mode="rb", delete_on_close=False) as temp:
        temp.close()
        cmd = [
            MKFS_CRAMFS.tool,
            "-N",
            cramfs_view.endianness.value,
            temp_flush_dir,
            temp.name,
        ]
        proc = await asyncio.create_subprocess_exec(
            *cmd,
        )
        returncode = await proc.wait()
        if proc.returncode:
            raise CalledProcessError(returncode=returncode, cmd=cmd)
        with open(temp.name, "rb") as new_fh:
            new_data = new_fh.read()
        # Passing in the original range effectively replaces the original data with the new data
        resource.queue_patch(Range(0, await resource.get_data_length()), new_data)

CramfsUnpacker (Unpacker)

Extract files and directories from a Linux Compressed ROM filesystems.

unpack(self, resource, config=None) async

Unpack the given resource.

Users should not call this method directly; rather, they should run Resource.run or Resource.unpack.

Parameters:

Name Type Description Default
resource Resource

The resource that is being unpacked

required
config

Optional config for unpacking. If an implementation provides a default, this default will always be used when config would otherwise be None. Note that a copy of the default config will be passed, so the default config values cannot be modified persistently by a component run.

None
Source code in ofrak/core/cramfs.py
async def unpack(self, resource: Resource, config=None):
    async with resource.temp_to_disk() as temp_path:
        with tempfile.TemporaryDirectory() as temp_parent:
            temp_flush_dir = os.path.join(temp_parent, "cramfs_extract")
            cmd = [
                FSCK_CRAMFS.tool,
                f"--extract={temp_flush_dir}",
                temp_path,
            ]
            proc = await asyncio.create_subprocess_exec(
                *cmd,
            )
            returncode = await proc.wait()
            if proc.returncode:
                raise CalledProcessError(returncode=returncode, cmd=cmd)

            data = await resource.get_data(Range(0, 4))
            if data == CRAMFS_MAGIC_BE:
                endianness = Endianness.BIG_ENDIAN
            else:
                endianness = Endianness.LITTLE_ENDIAN
            resource.add_view(Cramfs(endianness=endianness))
            cramfs_view = await resource.view_as(Cramfs)
            await cramfs_view.initialize_from_disk(temp_flush_dir)