Exemple #1
0
def create_inode_table():
    first_data_block = fs.bytes_to_int(
        superblock.get_field(superblock.s_first_data_block))
    inodetable_block = inodetable.load_inode(0)
    table_number = inodetable.get_table_number(0)
    inodetable_block.set_field(
        table_number, inodetable_block.i_mode, inodetable.S_IFDIR
        | inodetable.S_IXUSR | inodetable.S_IRUSR | inodetable.S_IWUSR
        | inodetable.S_IXOTH | inodetable.S_IROTH | inodetable.S_IWOTH
        | inodetable.S_IWGRP
        | inodetable.S_IRGRP | inodetable.S_IXGRP)
    inodetable_block.set_field(table_number, inodetable_block.i_uid, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_size, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_atime, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_mtime, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_ctime,
                               int(time.time()))
    inodetable_block.set_field(table_number, inodetable_block.i_dtime, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_gid, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_blocks, 1)
    inodetable_block.set_field(table_number, inodetable_block.i_flags, 0)
    block = bytearray(inodetable_block.i_block[sysblock.SIZE_INDEX])
    block[:superblock.s_first_data_block[sysblock.SIZE_INDEX]] = \
        first_data_block.to_bytes(superblock.s_first_data_block[sysblock.SIZE_INDEX], 'little')
    inodetable_block.set_field(table_number, inodetable_block.i_block,
                               bytes(block))
    inodetable_block.set_field(
        table_number, inodetable_block.i_pad,
        bytes(inodetable_block.i_pad[sysblock.SIZE_INDEX]))
    inodetable.unload_inode(0)
Exemple #2
0
    def auth(user, passwd):
        nonlocal uid, gid
        if uid != -1:
            raise AuthError

        uid, gid = 0, 0
        fd = openfile.open_file('/etc/passwd', openfile.O_RDONLY)

        inode = fdtable.get_inode(fd)
        inode_tn = inodetable.get_table_number(inode)
        file_inodetable_block = inodetable.load_inode(inode)
        file_size = fs.bytes_to_int(
            file_inodetable_block.get_field(inode_tn,
                                            file_inodetable_block.i_size))

        lines = readfile.read_by_offset(
            fd, file_size).decode(encoding='ASCII').splitlines()
        closefile.close_file(fd)
        uid, gid = -1, -1

        digest = hashlib.sha224(passwd.encode()).hexdigest()
        for l in lines:
            if l.lstrip()[0] != '#':
                u = tuple(l.split(':'))
                if u[0] == user:
                    if u[1] == digest and u[4] != 'nologin':
                        uid = int(u[2])
                        gid = int(u[3])

        if uid == -1:
            raise AuthError

        return uid
Exemple #3
0
def remove_file_record(offset):
    inode = get_record_inode_number(offset)
    inode_table_block = inodetable.load_inode(inode)
    inode_tn = inodetable.get_table_number(inode)
    i_block = inode_table_block.get_field(inode_tn, inode_table_block.i_block)
    inodetable.free_file_blocks(inode_table_block, inode, i_block)

    data_block_buffer.set_bytes(offset, fs.int_to_bytes(0, IN_FIELD_SIZE))
Exemple #4
0
def write_by_offset(fd, buf, nbytes):
    inode = fdtable.get_inode(fd)
    offset = fdtable.get_offset(fd)
    inode_tn = inodetable.get_table_number(inode)
    file_inodetable_block = inodetable.load_inode(inode)
    i_block = file_inodetable_block.get_field(inode_tn,
                                              file_inodetable_block.i_block)
    file_size = fs.bytes_to_int(
        file_inodetable_block.get_field(inode_tn,
                                        file_inodetable_block.i_size))
    blocks_count = fs.bytes_to_int(
        file_inodetable_block.get_field(inode_tn,
                                        file_inodetable_block.i_blocks))
    block_size = fs.bytes_to_int(
        superblock.get_field(superblock.s_log_block_size)) * 1024

    lbn = offset // block_size
    b_offset = offset % block_size

    if offset + nbytes > file_size:
        if b_offset + nbytes > block_size or lbn == blocks_count:
            inodetable.extend_file_blocks(file_inodetable_block, inode,
                                          i_block)
        file_inodetable_block.set_field(inode_tn, file_inodetable_block.i_size,
                                        offset + nbytes)

    bn = inodetable.lbn_to_bn(lbn, i_block)
    data_block_buffer.load(bn)
    if b_offset + nbytes > block_size:
        first_bytes_count = block_size - b_offset
        if first_bytes_count != 0:
            data_block_buffer.set_bytes(b_offset, buf[:first_bytes_count])
            data_block_buffer.unload(bn)
        bn = inodetable.lbn_to_bn(lbn + 1, i_block)
        data_block_buffer.load(bn)
        data_block_buffer.set_bytes(0, buf[first_bytes_count:nbytes])
    else:
        data_block_buffer.set_bytes(b_offset, buf)
    data_block_buffer.unload(bn)

    fdtable.set_offset(fd, offset + nbytes)

    file_inodetable_block.set_field(inode_tn, file_inodetable_block.i_mtime,
                                    int(time.time()))

    inodetable.unload_inode(inode)
Exemple #5
0
def chmod(path, mode):
    fd = openfile.create_file_descriptor(path, openfile.O_RDONLY, 0)
    ino = fdtable.get_inode(fd)
    inode_tn = inodetable.get_table_number(ino)
    inode_block = inodetable.load_inode(ino)
    i_mode = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_mode))
    i_uid = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_uid))

    try:
        if user.get_uid() != i_uid and user.get_uid() != 0:
            raise permissions.PermissionsError(i_mode)

        if i_mode & inodetable.S_IFREG == inodetable.S_IFREG:
            inode_block.set_field(inode_tn, inode_block.i_mode, inodetable.S_IFREG | int(mode))
        else:
            inode_block.set_field(inode_tn, inode_block.i_mode, inodetable.S_IFDIR | int(mode))
    finally:
        inodetable.unload_inode(ino)
        closefile.close_file(fd)
    return 0
Exemple #6
0
def write_to_end(fd, buf, nbytes):
    inode = fdtable.get_inode(fd)
    inode_tn = inodetable.get_table_number(inode)
    file_inodetable_block = inodetable.load_inode(inode)
    i_block = file_inodetable_block.get_field(inode_tn,
                                              file_inodetable_block.i_block)
    file_size = fs.bytes_to_int(
        file_inodetable_block.get_field(inode_tn,
                                        file_inodetable_block.i_size))
    block_size = fs.bytes_to_int(
        superblock.get_field(superblock.s_log_block_size)) * 1024

    last_block_size = file_size % block_size
    if last_block_size == 0:
        last_bn = inodetable.extend_file_blocks(file_inodetable_block, inode,
                                                i_block)
    else:
        last_bn = inodetable.get_last_file_bn(i_block)

    data_block_buffer.load(last_bn)
    if last_block_size + nbytes > block_size:
        last_bn = inodetable.extend_file_blocks(file_inodetable_block, inode,
                                                i_block)
        remaining_bytes_count = block_size - last_block_size
        data_block_buffer.set_bytes(last_block_size,
                                    buf[:remaining_bytes_count])
        data_block_buffer.unload(data_block_buffer.block_number)
        data_block_buffer.load(last_bn)
        data_block_buffer.set_bytes(0, buf[remaining_bytes_count:nbytes])
    else:
        data_block_buffer.set_bytes(last_block_size, buf[:nbytes])

    file_inodetable_block.set_field(inode_tn, file_inodetable_block.i_size,
                                    file_size + nbytes)
    data_block_buffer.unload(last_bn)

    file_inodetable_block.set_field(inode_tn, file_inodetable_block.i_mtime,
                                    int(time.time()))

    inodetable.unload_inode(inode)
Exemple #7
0
def read_by_offset(fd, nbytes):
    inode = fdtable.get_inode(fd)
    offset = fdtable.get_offset(fd)
    inode_tn = inodetable.get_table_number(inode)
    file_inodetable_block = inodetable.load_inode(inode)
    i_block = file_inodetable_block.get_field(inode_tn,
                                              file_inodetable_block.i_block)
    file_size = fs.bytes_to_int(
        file_inodetable_block.get_field(inode_tn,
                                        file_inodetable_block.i_size))
    block_size = fs.bytes_to_int(
        superblock.get_field(superblock.s_log_block_size)) * 1024

    if offset >= file_size:
        raise OffsetError(offset)

    lbn = offset // block_size
    b_offset = offset % block_size

    buf = bytearray()
    if b_offset + nbytes > block_size:
        first_bytes_count = block_size - b_offset
        data_block_buffer.load(inodetable.lbn_to_bn(lbn, i_block))
        buf[:first_bytes_count] = data_block_buffer.get_bytes(
            b_offset, first_bytes_count)
        data_block_buffer.load(inodetable.lbn_to_bn(lbn + 1, i_block))
        buf[first_bytes_count:nbytes] = data_block_buffer.get_bytes(
            0, nbytes - first_bytes_count)
    else:
        data_block_buffer.load(inodetable.lbn_to_bn(lbn, i_block))
        buf[:] = data_block_buffer.get_bytes(b_offset, nbytes)

    fdtable.set_offset(fd, offset + nbytes)

    file_inodetable_block.set_field(inode_tn, file_inodetable_block.i_atime,
                                    int(time.time()))

    inodetable.unload_inode(inode)
    return bytes(buf)
Exemple #8
0
def stat(path):
    fd = openfile.create_file_descriptor(path, openfile.O_STAT, 0)
    ino = fdtable.get_inode(fd)
    inode_tn = inodetable.get_table_number(ino)

    inode_block = inodetable.load_inode(ino)
    mode = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_mode))
    uid = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_uid))
    gid = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_gid))
    size = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_size))
    atime = fs.bytes_to_int(
        inode_block.get_field(inode_tn, inode_block.i_atime))
    mtime = fs.bytes_to_int(
        inode_block.get_field(inode_tn, inode_block.i_mtime))
    ctime = fs.bytes_to_int(
        inode_block.get_field(inode_tn, inode_block.i_ctime))
    blocks = fs.bytes_to_int(
        inode_block.get_field(inode_tn, inode_block.i_blocks))
    inodetable.unload_inode(ino)

    closefile.close_file(fd)

    return ino, mode, uid, gid, size, atime, mtime, ctime, blocks
Exemple #9
0
def create_file_descriptor(path, oflag, mode):
    names = [n for n in path.split('/') if n != '']

    dir_table_in = 0
    dir_inodetable_block = inodetable.load_inode(dir_table_in)
    dir_in = 0

    perm = inodetable.S_IRUSR | inodetable.S_IRGRP | inodetable.S_IROTH

    if not permissions.check_file_permissions(dir_inodetable_block, dir_in,
                                              perm):
        raise permissions.PermissionsError(perm)

    if path != '/':
        if len(names) > 1:
            for n in names[:-1]:
                offset = filerecord.find_file_record(dir_inodetable_block,
                                                     dir_table_in, n)

                inodetable.unload_inode(dir_in)

                if offset is None:
                    raise createfile.DirNotFoundError(n)

                dir_in = filerecord.get_record_inode_number(offset)
                dir_table_in = inodetable.get_table_number(dir_in)
                dir_inodetable_block = inodetable.load_inode(dir_in)

                if not permissions.check_file_permissions(
                        dir_inodetable_block, dir_in, perm):
                    raise permissions.PermissionsError(perm)

                if fs.bytes_to_int(
                        dir_inodetable_block.get_field(
                            dir_table_in, dir_inodetable_block.i_mode)
                ) & inodetable.S_IFDIR != inodetable.S_IFDIR:
                    raise createfile.DirNotFoundError(n)

        offset = filerecord.find_file_record(dir_inodetable_block,
                                             dir_table_in, names[-1])

        if oflag == O_WRONLY:
            perm = inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH
        if oflag == O_RDWR:
            perm |= inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH

        if offset is None:
            raise deletefile.FileNotExistsError(names[-1])

        inode_n = filerecord.get_record_inode_number(offset)
        inode_table_n = inodetable.get_table_number(inode_n)
        file_inodetable_block = inodetable.load_inode(inode_n)
    else:
        if oflag == O_WRONLY:
            perm = inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH
        if oflag == O_RDWR:
            perm |= inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH

        inode_n = dir_in
        inode_table_n = dir_table_in
        file_inodetable_block = dir_inodetable_block

    if fs.bytes_to_int(
            file_inodetable_block.get_field(
                inode_table_n, file_inodetable_block.i_mode)) & mode != mode:
        raise deletefile.WrongFileTypeError(names[-1])

    if oflag != O_STAT:
        if not permissions.check_file_permissions(file_inodetable_block,
                                                  inode_n, perm):
            raise permissions.PermissionsError(perm)

    inodetable.unload_inode(dir_in)
    inodetable.unload_inode(0)
    return fdtable.reserve_fd(inode_n)
Exemple #10
0
def create_file_record(path, mode):
    if path == '/':
        raise FileAlreadyExistsError('/')

    names = [n for n in path.split('/') if n != '']
    bg_block = gdtable.get_gdtableblock(0)
    inodebitmap.inode_bitmap.load(
        fs.bytes_to_int(bg_block.get_field(0, bg_block.bg_inode_bitmap)))
    inode_ign = inodebitmap.find_first_free_inode()
    inode_n = fs.ign_to_in(
        0,
        fs.bytes_to_int(superblock.get_field(superblock.s_inodes_per_group)),
        inode_ign)

    dir_table_in = 0
    dir_inodetable_block = inodetable.load_inode(dir_table_in)
    dir_in = 0

    perm = inodetable.S_IRUSR | inodetable.S_IRGRP | inodetable.S_IROTH
    if not permissions.check_file_permissions(dir_inodetable_block, dir_in,
                                              perm):
        raise permissions.PermissionsError(perm)

    if len(names) > 1:
        for n in names[:-1]:
            offset = filerecord.find_file_record(dir_inodetable_block,
                                                 dir_table_in, n)

            inodetable.unload_inode(dir_in)

            if offset is None:
                raise DirNotFoundError(n)

            dir_in = filerecord.get_record_inode_number(offset)
            dir_table_in = inodetable.get_table_number(dir_in)
            dir_inodetable_block = inodetable.load_inode(dir_in)

            if not permissions.check_file_permissions(dir_inodetable_block,
                                                      dir_in, perm):
                raise permissions.PermissionsError(perm)

            if fs.bytes_to_int(
                    dir_inodetable_block.get_field(dir_table_in,
                                                   dir_inodetable_block.i_mode)
            ) & inodetable.S_IFDIR != inodetable.S_IFDIR:
                raise DirNotFoundError(n)

    perm = inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH
    if not permissions.check_file_permissions(dir_inodetable_block, dir_in,
                                              perm):
        raise permissions.PermissionsError(perm)

    offset = filerecord.find_file_record(dir_inodetable_block, dir_table_in,
                                         names[-1])
    if offset is None:
        filerecord.create_file_record(dir_inodetable_block, dir_table_in,
                                      inode_n, names[-1])
        dir_inodetable_block.set_field(dir_table_in,
                                       dir_inodetable_block.i_mtime,
                                       int(time.time()))
    else:
        raise FileAlreadyExistsError(names[-1])

    inodetable_block = inodetable.load_inode(inode_n)
    inodetable_block.set_field(inode_ign, inodetable_block.i_mode, mode)
    inodetable_block.set_field(inode_ign, inodetable_block.i_uid,
                               user.get_uid())
    inodetable_block.set_field(inode_ign, inodetable_block.i_size, 0)
    inodetable_block.set_field(inode_ign, inodetable_block.i_atime, 0)
    inodetable_block.set_field(inode_ign, inodetable_block.i_mtime, 0)
    inodetable_block.set_field(inode_ign, inodetable_block.i_ctime,
                               int(time.time()))
    inodetable_block.set_field(inode_ign, inodetable_block.i_dtime, 0)
    inodetable_block.set_field(inode_ign, inodetable_block.i_gid,
                               user.get_gid())
    inodetable_block.set_field(inode_ign, inodetable_block.i_blocks, 0)
    inodetable_block.set_field(inode_ign, inodetable_block.i_flags, 0)
    inodetable_block.set_field(inode_ign, inodetable_block.i_block, bytes(60))
    inodetable_block.set_field(
        inode_ign, inodetable_block.i_pad,
        bytes(inodetable_block.i_pad[sysblock.SIZE_INDEX]))
    inodebitmap.set_used_inode(inode_ign)
    inodebitmap.inode_bitmap.unload(
        fs.bytes_to_int(bg_block.get_field(0, bg_block.bg_inode_bitmap)))
    inodetable.unload_inode(inode_n)
    inodetable.unload_inode(0)
    return fdtable.reserve_fd(inode_n)
Exemple #11
0
def delete_file_record(path, mode):
    if path == '/':
        raise WrongFileTypeError(path)

    names = [n for n in path.split('/') if n != '']
    bg_block = gdtable.get_gdtableblock(0)
    inodebitmap.inode_bitmap.load(
        fs.bytes_to_int(bg_block.get_field(0, bg_block.bg_inode_bitmap)))

    dir_table_in = 0
    dir_inodetable_block = inodetable.load_inode(dir_table_in)
    dir_in = 0

    perm = inodetable.S_IRUSR | inodetable.S_IRGRP | inodetable.S_IROTH
    if not permissions.check_file_permissions(dir_inodetable_block, dir_in,
                                              perm):
        raise permissions.PermissionsError(perm)

    if len(names) > 1:
        for n in names[:-1]:
            offset = filerecord.find_file_record(dir_inodetable_block,
                                                 dir_table_in, n)
            if dir_in != 0:
                inodetable.unload_inode(dir_in)

            if offset is None:
                raise createfile.DirNotFoundError(n)

            dir_in = filerecord.get_record_inode_number(offset)
            dir_table_in = inodetable.get_table_number(dir_in)
            dir_inodetable_block = inodetable.load_inode(dir_in)

            if not permissions.check_file_permissions(dir_inodetable_block,
                                                      dir_in, perm):
                raise permissions.PermissionsError(perm)

            if fs.bytes_to_int(
                    dir_inodetable_block.get_field(dir_table_in,
                                                   dir_inodetable_block.i_mode)
            ) & inodetable.S_IFDIR != inodetable.S_IFDIR:
                raise createfile.DirNotFoundError(n)

    perm = inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH
    if not permissions.check_file_permissions(dir_inodetable_block, dir_in,
                                              perm):
        raise permissions.PermissionsError(perm)

    offset = filerecord.find_file_record(dir_inodetable_block, dir_table_in,
                                         names[-1])
    bn = data_block_buffer.block_number

    if offset is None:
        raise FileNotExistsError(names[-1])

    inode_n = filerecord.get_record_inode_number(offset)
    inode_table_n = inodetable.get_table_number(inode_n)
    file_inodetable_block = inodetable.load_inode(inode_n)

    if fs.bytes_to_int(
            file_inodetable_block.get_field(
                inode_table_n, file_inodetable_block.i_mode)) & mode != mode:
        raise WrongFileTypeError(names[-1])

    if mode & inodetable.S_IFDIR == inodetable.S_IFDIR:
        fd = opendir.opendir(path)
        try:
            readdir.readdir(fd)
            raise DirIsNotEmpty(path)
        except readfile.OffsetError:
            pass
        finally:
            closedir.closedir(fd)

    data_block_buffer.load(bn)
    filerecord.remove_file_record(offset)
    dir_inodetable_block.set_field(dir_table_in, dir_inodetable_block.i_mtime,
                                   int(time.time()))
    inodebitmap.set_free_inode(inode_table_n)
    inodebitmap.inode_bitmap.unload(
        fs.bytes_to_int(bg_block.get_field(0, bg_block.bg_inode_bitmap)))
    inodetable.unload_inode(inode_n)
    inodetable.unload_inode(dir_in)
    inodetable.unload_inode(0)
    data_block_buffer.unload(data_block_buffer.block_number)