예제 #1
0
 def save_to_block(self, block: int) -> None:
     """ Set the metadata space of the given block (from 0 to 38, inclusive) to this metadata. """
     full_block = FileTable().read_block(block)
     data_section = full_block[START_OF_CONTENT:]
     new_bytes = self.form_bytes() + data_section
     write_block(block, new_bytes)
     FMLog.success(f"Wrote new metadata to block {block}")
예제 #2
0
    def edit_file(self, first_block: int, data: bytes, offset: int) -> int:
        """
        Returns the number of bytes written
        """
        filetable = FileTable()

        (metadata, old_data) = ItemFactory(first_block).create().get_data()

        data_to_keep = old_data[0:offset]
        file_size = len(data + data_to_keep)

        metadata.update_all_times()
        metadata.SIZE = file_size

        if not metadata.LOCATION:
            FMLog.error(
                "Cannot edit file that does not have location in metadata")
            raise FuseOSError(ENOENT)

        to_write = metadata.form_bytes() + data_to_keep + bytearray(data)

        locations = filetable.write_bytes_to_block(
            to_write,
            filetable.get_file_blocks(metadata.LOCATION),
        )

        filetable.write_to_table(locations)

        return len(data)
예제 #3
0
    def link_file(self, file_location: int, with_name: str) -> None:
        """ Links an existing file to this directory """
        (metadata, dir_data) = self.get_dir_data()
        new_dir_data = (metadata + self.clear_nulls_from_bytes(dir_data, 1) +
                        int_to_bytes(file_location, 1))
        self.save(new_dir_data)
        FMLog.success(
            f"Linked file to dirblock {self.block}, with data meta {metadata} and data {self.clear_nulls_from_bytes(dir_data,1)+bytearray(file_location)}"
        )

        file_meta = structures.Filesystem.Filesystem().get_block_metadata(
            file_location)
        file_meta.NAME = with_name
        file_meta.save_to_block(file_location)
예제 #4
0
    def path_resolver(self, path: str) -> int:
        """ Given a path, get the block index of the basename of the path. """
        if path == "/":
            return 1

        chunks = path.split(os.path.sep)[1:]

        last_chunk = chunks[-1]

        current_dir = self.get_root()
        found = False
        final_location = None
        is_at_end = False

        for chunk in chunks:
            possible_file = last_chunk == chunk
            found = False
            directory_files = current_dir.get_files(strip_null=True)
            for filename, file_location, filetype in directory_files:
                if filename == chunk:
                    # found a valid name
                    if filetype == 1 and not possible_file:
                        # impossible
                        FMLog.error(
                            "Filetype indicated this is a file, but the path states this should not be a file."
                        )
                        raise FuseOSError(EINVAL)
                    final_location = file_location
                    found = True
                    if possible_file:
                        is_at_end = True
                    else:
                        current_dir = self.dir_from_block(file_location)
                    break

            if not found:
                return -1

        if not is_at_end:
            raise FuseOSError(ENOENT)

        if not final_location:
            return -1

        return final_location
예제 #5
0
 def file_from_block(self, block_index: int):
     data = self.get_block_metadata(block_index)
     if data.TYPE == 0:
         FMLog.error(f"Expected file, found directory")
         raise FuseOSError(ENOENT)
     return File(block_index)
예제 #6
0
 def dir_from_block(self, block_index: int):
     data = self.get_block_metadata(block_index)
     if data.TYPE == 1:
         FMLog.error(f"Expected directory, found file")
         raise FuseOSError(ENOENT)
     return DirFactory(block_index).construct()
예제 #7
0
파일: small.py 프로젝트: frasermcc9/fmfs
        block_location = fs.path_resolver(path)
        metadata = fs.get_block_metadata(block_location)
        metadata.ATIME = int(atime)
        metadata.MTIME = int(mtime)
        metadata.save_to_block(block_location)

    def write(self, path: str, data: bytes, offset: int, fh):
        fs = Filesystem()

        block_of_interest = fs.path_resolver(path)
        size = fs.edit_file(block_of_interest, data, offset)

        return size


if __name__ == "__main__":
    import argparse

    version = platform.python_version_tuple()
    if not (int(version[0]) == 3 and (int(version[1]) >= 8)):
        FMLog.error(
            f"Python 3.8.5 may be required. Features are used that might not be in your detected version, Python {platform.python_version()}."
        )

    parser = argparse.ArgumentParser()
    parser.add_argument("mount")
    args = parser.parse_args()

    logging.basicConfig(level=logging.DEBUG)
    fuse = FUSE(Small(), args.mount, foreground=True)
예제 #8
0
파일: format.py 프로젝트: frasermcc9/fmfs
# ************************************************************************

import os
from structures.factories.MetadataFactory import MetadataFactory
from time import time
from disktools import BLOCK_SIZE, NUM_BLOCKS, write_block
from constants import END_OF_FILE, FREE_SPACE
from stat import S_IFDIR
from util.FMLog import FMLog

# Filetable
initial_table_block = bytearray([FREE_SPACE] * NUM_BLOCKS)
initial_table_block[0] = END_OF_FILE
initial_table_block[1] = END_OF_FILE

FMLog.warn("✔  Created filetable in disk block 0")

now = time()
dir_meta = (MetadataFactory().set_with_params(
    LOCATION=0x01,
    MODE=(S_IFDIR | 0o755),
    ATIME=int(now),
    CTIME=int(now),
    MTIME=int(now),
    NLINKS=2,
    GID=os.getgid(),
    UID=os.getuid(),
    NAME="FMFS",
    TYPE=0,
    SIZE=64,
).construct().form_bytes())