Exemplo n.º 1
0
    def add_file(self, file_name: str, data: str,
                 metadata: Metadata) -> AbstractItem:
        """Add a file to the filesystem, in this directory. This will write the
        file to the disk, add it to this directory entry, and add it to the
        filetable."""
        filetable = FileTable()

        # get a new block to place the file at
        first_loc = filetable.find_free_block()

        existing = self.ensure_uniqueness(file_name)
        if existing != -1:
            # file with this name exists, so destroy existing data
            filetable.purge_full_file(existing)

        # set the LOCATION metadata field to this location
        metadata.LOCATION = first_loc

        # Write the data to the blocks, then add these blocks to the filetable
        blocks_to_write = filetable.write_to_block(data, metadata.form_bytes())
        filetable.write_to_table(blocks_to_write)

        location_as_bytes = int_to_bytes(blocks_to_write[0], 1)
        [dir_metadata, dir_refs] = self.get_dir_data()
        dir_data = (dir_metadata + self.clear_nulls_from_bytes(dir_refs, 1) +
                    location_as_bytes)

        self.save(dir_data)
        return self.smart_resolve(block=blocks_to_write[0], name=None)
Exemplo n.º 2
0
    def internal_item_maker(self, path: str, mode: int,
                            f_type: int) -> AbstractItem:
        [dirname, filename] = self.get_path_and_base(path)
        block = self.path_resolver(dirname)
        dirent = self.dir_from_block(block_index=block)
        child_links = 1
        base_mode = S_IFREG

        if f_type == 0:
            current_links = dirent.get_metadata().NLINKS or 0
            dirent.update_metadata(Metadata(NLINKS=current_links + 1))
            child_links = 2
            base_mode = S_IFDIR

        return dirent.add_file(
            file_name=filename,
            data="",
            metadata=MetadataFactory(
                MODE=(base_mode | mode),
                ATIME=int(time()),
                MTIME=int(time()),
                CTIME=int(time()),
                SIZE=0 if f_type == 1 else 64,
                NLINKS=child_links,
                NAME=filename,
                TYPE=f_type,
                UID=os.getuid(),
                GID=os.getgid(),
            ).construct(),
        )
Exemplo n.º 3
0
    def rmdir(self, path: str):
        # with multiple level support, need to raise ENOTEMPTY if contains any files
        fs = Filesystem()
        dir_to_remove = fs.dir_from_block(fs.path_resolver(path))
        if not dir_to_remove.deleteable():
            raise FuseOSError(ENOTEMPTY)

        (parent_path, _) = fs.get_path_and_base(path)
        parent_loc = fs.path_resolver(parent_path)
        parent_dir = fs.dir_from_block(parent_loc)
        parent_dir.remove_file(dir_to_remove.block)

        current_links = (
            Metadata.build_metadata(parent_dir.get_dir_data()[0]).NLINKS or 2
        )
        parent_dir.update_metadata(Metadata(NLINKS=current_links - 1))
Exemplo n.º 4
0
 def construct(self) -> Metadata:
     return Metadata.build_metadata(
         str_to_bytes(self.name or "", 16) +
         int_to_bytes(self.size or 0, 2) +
         int_to_bytes(self.nlinks or 0, 1) +
         int_to_bytes(self.mode or 0, 2) + int_to_bytes(self.uid or 0, 2) +
         int_to_bytes(self.gid or 0, 2) + int_to_bytes(self.ctime or 0, 4) +
         int_to_bytes(self.mtime or 0, 4) +
         int_to_bytes(self.atime or 0, 4) +
         int_to_bytes(self.location or 0, 1) +
         int_to_bytes(self.type or 0, 1))
Exemplo n.º 5
0
    def save(self,
             new_data: bytearray,
             metadata_only_change: bool = False) -> None:
        filetable = FileTable()

        blocks_from_dir = filetable.get_file_blocks(self.block)

        locations = filetable.write_bytes_to_block(new_data, blocks_from_dir)

        if not metadata_only_change:
            self.update_metadata(Metadata(SIZE=len(locations) * 64))

        filetable.write_to_table(locations)
Exemplo n.º 6
0
 def get_block_metadata(self, block_index: int) -> Metadata:
     file = read_block(block_index)
     return Metadata.build_metadata(file[0:END_OF_METADATA])
Exemplo n.º 7
0
    def update_metadata(self, new_metadata: Metadata) -> None:
        (existing_metadata, normal_data) = self.get_data()

        new_metadata.ATIME = new_metadata.ATIME or existing_metadata.ATIME
        new_metadata.CTIME = new_metadata.CTIME or existing_metadata.CTIME
        new_metadata.MTIME = new_metadata.MTIME or existing_metadata.MTIME
        new_metadata.GID = new_metadata.GID or existing_metadata.GID
        new_metadata.UID = new_metadata.UID or existing_metadata.UID
        new_metadata.LOCATION = new_metadata.LOCATION or existing_metadata.LOCATION
        new_metadata.MODE = new_metadata.MODE or existing_metadata.MODE
        new_metadata.NLINKS = new_metadata.NLINKS or existing_metadata.NLINKS
        new_metadata.SIZE = new_metadata.SIZE or existing_metadata.SIZE
        new_metadata.TYPE = new_metadata.TYPE or existing_metadata.TYPE
        new_metadata.NAME = new_metadata.NAME or existing_metadata.NAME

        self.save(new_metadata.form_bytes() + normal_data, True)
Exemplo n.º 8
0
 def get_metadata(self) -> Metadata:
     data = FileTable().read_block(self.block)
     return Metadata.build_metadata(data[START_OF_METADATA:END_OF_METADATA])