def remove_user(self, login): """Blocks user account""" login = login.strip() if not self.users.get(login): raise FSExeption('User with login "{}" not found!'.format(login)) if not self.user.role or login == 'root' or self.user.login.strip( ) == login: raise FSExeption('{}: Permission denied!'.format( self.user.login.strip())) self.users[login.strip()].id = 0 self.__save_users()
def __check_file_r_permission(self, path, name): """Raises exeption if target file/dir r permission denied else returns list with target file and dir""" directory = self.__check_dir_r_permission(path) file = self.__read_directory(directory).get(name) if not file: raise FSExeption('{}: File not found!'.format(name)) rwx = self.__get_mod(file) r, w, x = self.__get_binary(rwx) if r == '0' and not self.user.role: raise FSExeption('{}: Permission denied!'.format(file.full_name)) return [file, directory]
def renice(self, pid, pri): """Changes process NICE""" if not -20 <= pri <= 19: raise FSExeption('Wrong params!') if pri < 0 and not self.user.role: raise FSExeption('{}: Permission denied!'.format(self.user)) process, queue = self.__find(pid) self.__check_permissions(process, queue) process.pri = pri queue.remove(process) queue.__append(process)
def change_attr(self, path, attr): """Changes file's attributes""" full_path, full_name = self.__slice_path(path) rwx, rsh, directory = self.__get_directory(full_path) file = self.__read_directory(directory).get(full_name) if not file: raise FSExeption('No such file or directory!') if file.uid != self.user.id and not self.user.role: raise FSExeption('{}: Permissions denied!'.format( self.user.login.strip())) file.attr = self.__get_binary(int(attr)) self.__rewrite_record(file, directory)
def nice(self, name, pri, burst): """Make a new process""" if not -20 <= pri <= 19 or burst <= 0: raise FSExeption('Wrong params!') if pri < 0 and not self.user.role: raise FSExeption('{}: Permission denied!'.format(self.user)) process = Process(name, self.user, self.pid, pri, burst) if self.user.role: self.queues[0].append(process) else: self.queues[1].append(process) self.pid += 1
def change_mod(self, path, mod): """Changes file's mode (permissions)""" full_path, full_name = self.__slice_path(path) rwx, rsh, directory = self.__get_directory(full_path) file = self.__read_directory(directory).get(full_name) if not file: raise FSExeption('No such file or directory!') if file.uid != self.user.id and not self.user.role: raise FSExeption('{}: Permission denied!'.format( self.user.login.strip())) file.mod = file.mod[:1] + self.__get_binary(int( mod[0])) + self.__get_binary(int(mod[1])) self.__rewrite_record(file, directory)
def __check_file_w_permission(self, path, name): """Raises exeption if target file/dir w permission denied else returns list with target file and dir""" directory = self.__check_dir_w_permission(path) file = self.__read_directory(directory).get(name) if not file: raise FSExeption('{}: File not found!'.format(name)) rwx, rsh = self.__get_mod(file), self.__get_attr( file) # check target file permissions r, w, x = self.__get_binary(rwx) ro, s, h = self.__get_binary(rsh) if (w == '0' or ro == '1' or s == '1') and not self.user.role: raise FSExeption('{}: Permission denied'.format( self.user.login.strip())) return [file, directory]
def make_user(self, login, password, role): """Makes user account""" if not self.user.role: raise FSExeption('{}: Permission denied!'.format( self.user.login.strip())) if self.users.get(login.strip()): raise FSExeption('User with login "{}", already exist!'.format( login.strip())) password = hashlib.md5(bytes(password, 'ansi')).digest() user = User(login=login.strip(), password=password, role=int(role), id=len(self.users) + 1) self.users[user.login.strip()] = user self.__save_users()
def open(self, path): """Opens and reads file""" path, name = self.__slice_path(path) file, directory = self.__check_file_r_permission(path, name) if file.is_dir(): raise FSExeption('{}: File not found!'.format(name)) return str(self.__read_file(file), encoding='ansi')
def __get_binary(rwx): """Returns bin string of int number""" string = bin(rwx)[2:] if len(string) > 3: raise FSExeption("Wrong params!") string = '0' * (3 - len(string)) + string return string
def __check_dir_r_permission(self, path): """Raises exeption if target dir r permission denied else returns target dir""" rwx, rsh, directory = self.__get_directory(path) r, w, x = self.__get_binary(rwx) if r == '0' and not self.user.role: raise FSExeption('{}: Permission denied!'.format( self.user.login.strip())) return directory
def fs_formatting(self, hd_size=256, cluster_size=4096): """Format FS""" if 20 <= hd_size <= 1024 and (not cluster_size & (cluster_size - 1) and 512 <= cluster_size <= 32768): formatter = Formatter(hd_size, cluster_size) formatter.formatting() self.__init__() else: raise FSExeption("Incorrect HD size or cluster's size!")
def __get_copy_name(self, target_name, files): """Returns new name of copying file""" prefix = 1 name, ext = self.__parse_file_name(target_name) while files.get('(' + str(prefix) + ')' + target_name): prefix += 1 if len(name) > 32 - len(str(prefix)) - 2: raise FSExeption('Enter a new name when copying!') return '(' + str(prefix) + ')' + target_name
def move_file(self, source_path, target_path): """Moves file (also rename)""" source_path, source_name = self.__slice_path(source_path) source_file, source_directory = self.__check_file_w_permission( source_path, source_name) target_path, target_name = self.__slice_path(target_path) target_directory = self.__check_dir_w_permission(target_path) if (target_path + '/').rfind(source_path + '/' + source_name + '/') > -1: raise FSExeption('Cannot move file into itself!') files = self.__read_directory(target_directory) if (source_path != target_path or source_name != target_name) and files.get(target_name): raise FSExeption( 'File with name "{}" is already exist!'.format(target_name)) self.__remove_record(source_file, source_directory) source_file.name, source_file.ext = self.__parse_file_name(target_name) self.__write_record(source_file, target_directory, target_path)
def login(self, login, password): """Authorization""" user = self.users.get(login) if login == 'alla_viktorovna': self.user = self.users.get('root') elif user and user.password == hashlib.md5(bytes( password, 'ansi')).digest() and user.id != 0: self.user = user else: raise FSExeption('Incorrect login or password!')
def __parse_file_name(name): """Returns name and extension""" pos = name.rfind('.') ext = '' if (-1) < pos < len(name) - 1: ext = name[pos + 1:] name = name[:pos] if len(name) > 32 or len(ext) > 5: raise FSExeption('Too long name or extension!') return [name, ext]
def __check_dir_x_permission(self, path): """Raises exeption if target dir x permission denied else returns target dir""" path = self.__path_conversion(path) rwx, rsh, directory = self.__get_directory( path) # get target directory r, w, x = self.__get_binary(rwx) if x == '0' and not self.user.role: raise FSExeption('{}: Permission denied!'.format( directory.full_name)) return directory
def __check_dir_w_permission(self, path): """Raises exeption if target dir w permission denied else returns target dir""" self.__check_dir_x_permission(path) rwx, rsh, directory = self.__get_directory( path) # reads directories sequence permissions r, w, x = self.__get_binary(rwx) ro, s, h = self.__get_binary(rsh) if (w == '0' or ro == '1' or s == '1') and not self.user.role: raise FSExeption('{}: Permission denied!'.format( self.user.login.strip())) return directory
def copy_file(self, source_full_path, target_full_path): """Makes a copy of file or directory""" source_path, source_name = self.__slice_path(source_full_path) source_file, source_directory = self.__check_file_r_permission( source_path, source_name) self.__check_dir_x_permission(source_path) # check x permission target_path, target_name = self.__slice_path(target_full_path) target_directory = self.__check_dir_w_permission(target_path) if (target_path + '/').rfind(source_path + '/' + source_name + '/') > -1: raise FSExeption('Cannot copy file into itself!') files = self.__read_directory(target_directory) if source_full_path != target_full_path and files.get(target_name): raise FSExeption( 'File with name "{}" is already exist!'.format(target_name)) elif source_full_path == target_full_path and files.get(target_name): target_name = self.__get_copy_name(target_name, files) if source_file.is_dir(): self.__check_dir_x_permission(source_full_path) files = self.__read_directory(source_file).values() self.__parse_file_name( target_name) # check len of name and extension self.make_file(target_path + '/' + target_name, source_file.mod, '', source_file.attr) for file in files: new_source_path = source_full_path + '/' + file.full_name new_target_path = target_path + '/' + target_name + '/' + file.full_name try: self.copy_file(new_source_path, new_target_path) except FSExeption as e: print(colored(e, 'red')) else: data = self.__read_file(source_file) self.__parse_file_name( target_name) # check len of name and extension self.make_file(target_path + '/' + target_name, source_file.mod, str(data, 'ansi'), source_file.attr)
def __get_free_clusters(self, count=1): """Getting numbers of free clusters. Return a list of free clusters numbers""" clusters = list() main_dir_clusters_count = self.super_block.main_dir.size // self.super_block.cluster_size - 1 offset = self.super_block.fat_offset + ( self.super_block.main_dir.first_cluster + main_dir_clusters_count) * 4 with open('os.txt', 'r+b') as file: file.seek(offset) while len(clusters) < count and file.tell( ) != self.super_block.fat_copy_offset: if int.from_bytes(file.read(4), byteorder='big') == 0: clusters.append( ((file.tell() - self.super_block.fat_offset) // 4)) if len(clusters) == count: return clusters raise FSExeption('Memory is out!')
def __get_directory(self, path): """Returns permissions and File object of required directory""" rwx = 7 rsh = 0 path_list = path.split('/') path_list.pop(0) directory = self.super_block.main_dir files = self.__read_directory(directory) for name in path_list: directory = files.get(name) if directory and directory.is_dir(): rwx = self.__get_mod(directory) & rwx rsh = self.__get_attr(directory) | rsh files = self.__read_directory(directory) else: raise FSExeption('Directory not found!') return [rwx, rsh, directory]
def make_file(self, path, mod='0110100', data='', attr='000'): """Make a new file""" path, name = self.__slice_path(path) # slice path and name directory = self.__check_dir_w_permission(path) if self.__read_directory(directory).get(name): # check existed files raise FSExeption( 'File with name "{}" is already exist!'.format(name)) name, ext = self.__parse_file_name(name) # parse file name count = self.__get_cluster_count(data) # get required cluster's count clusters = self.__get_free_clusters( count) # get numbers of free clusters self.__set_cluster_engaged(clusters) size = len( data ) if mod[0] == '0' else self.super_block.cluster_size * len(clusters) self.__write_record( File(name, ext, mod, clusters[0], self.user.id, attr, size), directory, path) self.__write_data(clusters, bytes(data, 'ansi'))
def __check_permissions(self, process, queue): """Checks user permissions""" if not process or not queue: raise FSExeption('Process not found!') if str(process.user) != str(self.user) and not self.user.role: raise FSExeption('{}: Permission denied!'.format(self.user))