def update_owner(self, path, uid, gid): for i in range(1, NUM_BLOCKS, 1): block = disktools.read_block(i) if block[NAME_START:NAME_FINISH].decode().rstrip('\x00') == path: block[UID_START:UID_FINISH] = disktools.int_to_bytes(uid, 2) block[GID_START:GID_FINISH] = disktools.int_to_bytes(gid, 2) disktools.write_block(i, block) return 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))
def form_bytes(self) -> bytearray: """ Get the bytearray representation of the metadata """ return (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))
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)
def update_mode(self, path, mode): for i in range(1, NUM_BLOCKS, 1): block = disktools.read_block(i) if block[NAME_START:NAME_FINISH].decode().rstrip('\x00') == path: block[MODE_START:MODE_FINISH] = disktools.int_to_bytes(mode, 2) disktools.write_block(i, block) return 0
def update_file_location(self, path, bitmap): for i in range(1, NUM_BLOCKS, 1): block = disktools.read_block(i) if block[NAME_START:NAME_FINISH].decode().rstrip('\x00') == path: block[LOCATION_START:LOCATION_FINISH] = disktools.int_to_bytes( bitmap, 2) disktools.write_block(i, block) return 0
def set_inode(self, name, mode, ctime, mtime, atime, nlink, uid, gid, size, block_num): block = disktools.read_block(block_num) block[MODE_START:MODE_FINISH] = disktools.int_to_bytes(mode, 2) block[UID_START:UID_FINISH] = disktools.int_to_bytes(uid, 2) block[GID_START:GID_FINISH] = disktools.int_to_bytes(gid, 2) block[NLINK_START:NLINK_FINISH] = disktools.int_to_bytes(nlink, 1) block[SIZE_START:SIZE_FINISH] = disktools.int_to_bytes(size, 2) block[CTIME_START:CTIME_FINISH] = disktools.int_to_bytes(int(ctime), 4) block[MTIME_START:MTIME_FINISH] = disktools.int_to_bytes(int(mtime), 4) block[ATIME_START:ATIME_FINISH] = disktools.int_to_bytes(int(atime), 4) block[LOCATION_START:LOCATION_FINISH] = disktools.int_to_bytes(0, 2) block[NAME_START:NAME_FINISH] = name.encode() return block
def update_bit_map(self, used_block): block = disktools.read_block(0) # get the int number of bitmap bitmap = disktools.bytes_to_int(block[BITMAP_START:BITMAP_FINISH]) for i in used_block: bitmap = bits.toggleBit(bitmap, i) block[BITMAP_START:BITMAP_FINISH] = disktools.int_to_bytes(bitmap, 2) disktools.write_block(0, block) return bitmap
def update_nlink(self, path, update): for i in range(0, NUM_BLOCKS, 1): block = disktools.read_block(i) if block[NAME_START:NAME_FINISH].decode().rstrip('\x00') == path: new_nlink = disktools.bytes_to_int( block[NLINK_START:NLINK_FINISH]) + update block[NLINK_START:NLINK_FINISH] = disktools.int_to_bytes( new_nlink, 1) disktools.write_block(i, block) return 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)
def initial_free_block_bitmap(self): # initialise the bitmap int value to 0 bitmap = 0 # counter for count the blocks count = 0 for i in range(NUM_BLOCKS): # read each block in the disk block = disktools.read_block(i) # set the value to 0 for the non-free block in bit map if disktools.bytes_to_int(block) != 0: bitmap = bits.clearBit(bitmap, count) count += 1 else: bitmap = bits.setBit(bitmap, count) count += 1 # set the first block to 1 which means it is not free(will store bitmap into block 0). bitmap = bits.clearBit(bitmap, 0) # write the bitmap value at the first two bytes at block 0 bitmap_disk = disktools.read_block(0) bitmap_disk[BITMAP_START:BITMAP_FINISH] = disktools.int_to_bytes( bitmap, 2) disktools.write_block(0, bitmap_disk)