예제 #1
0
파일: fs.cpp 프로젝트: e-learning/aptu-os
void FS::copy(FileDescriptor src_file, FileDescriptor & dst_fold, std::string dst_filename){
	Block * src_block = new Block(src_file.first_block, config.block_size, _root);
	read_data(&src_file, sizeof(FileDescriptor), src_block);
	char * data = new char[src_file.size];
	read_data(data, src_file.size, src_block);

    FileDescriptor file;
    Block * file_block = get_free_block();
	write_data(&file, sizeof(FileDescriptor), file_block);
	write_data(data, src_file.size, file_block);

	Block * dst_block = new Block(dst_fold.first_block, config.block_size, _root);


    bool found = false;
	for(auto it = DirIterator(*this, dst_fold); it != DirIterator(*this); ++it){
		FileDescriptor f = *it;
		if (std::string(f.filename) == dst_filename ){
            if( f.directory){
                found = true;
                dst_fold = f;
                dst_block = new Block(dst_fold.first_block, config.block_size, _root);
            } else{
                throw std::runtime_error("File already exist");
            } 
        } 
	}

	file.first_block = file_block->get_index();
    if(!found){
        file.set_filename(dst_filename);
    } else{
        file.set_filename(src_file.filename);
    }
	file.parent_file = dst_fold.first_block;
	file.size = src_file.size;
    file.directory = src_file.directory;

	if(dst_fold.first_child != -1){
		Block * nb = new Block(dst_fold.first_child, config.block_size, _root);
		FileDescriptor nd;
		read_data(&nd, sizeof(FileDescriptor), nb);
		nd.prev_file = file.first_block;
		update_descriptor(nd,nb);
		file.next_file = nd.first_block;
	}
	dst_fold.first_child = file.first_block;
	update_descriptor(dst_fold, dst_block);
    update_descriptor(file, file_block);

	if(src_file.directory){
		for(auto it = DirIterator(*this, src_file); it != DirIterator(*this); ++it){
			FileDescriptor f = *it;
			copy(f, file, f.filename);
		}
	}
}
예제 #2
0
파일: fs.cpp 프로젝트: e-learning/aptu-os
void FS::import(std::string host_file, std::string fs_file){
    if (!initialized) {throw "Not initialized";}
    read_meta();
    
	if(fs_file[fs_file.size() - 1] == '/'){
		fs_file = fs_file.substr(0, fs_file.size() - 1);
	}
    int last_match = fs_file.find_last_of("/");
    std::string fs_file_path = fs_file.substr(0, last_match + 1);
    std::string fs_file_name = fs_file.substr(last_match + 1);
    
    FileDescriptor dst_fold = get_file(fs_file_path, false, false);
    Block * dst_block = new Block(dst_fold.first_block, config.block_size, _root);
    for(auto it = DirIterator(*this, dst_fold); it != DirIterator(*this); ++it){
		FileDescriptor file = *it;
		if (std::string(file.filename) == fs_file_name ) throw std::runtime_error("File already exist");
	}

	FileDescriptor file;
    Block * file_block = get_free_block();
	std::ifstream File (host_file, std::ios::in | std::ios::binary);
	if( File.fail() ) throw std::runtime_error("Can't open " + host_file);
	File.seekg( 0, std::ios::end );
	int fileLen = File.tellg();
	file.size = fileLen;
	File.seekg( 0, std::ios::beg);
	char * data = new char[fileLen];
	File.read(data, fileLen);
	if(File.fail()) throw std::runtime_error("Can't read file " + host_file);
	File.close();

	write_data(&file, sizeof(FileDescriptor), file_block);
	write_data(data, fileLen, file_block);

	file.directory = false;
    file.set_filename(fs_file_name);

	file.first_block = file_block->get_index();
	file.parent_file = dst_fold.first_block;
	file.prev_file = -1;
	file.next_file = -1;
	if(dst_fold.first_child != -1){
		Block * nb = new Block(dst_fold.first_child, config.block_size, _root);
		FileDescriptor nd;
		read_data(&nd, sizeof(FileDescriptor), nb);
		nd.prev_file = file.first_block;
		update_descriptor(nd,nb);
		file.next_file = nd.first_block;
	}
	dst_fold.first_child = file.first_block;
	update_descriptor(dst_fold, dst_block);
    update_descriptor(file, file_block);
	write_meta();
}
예제 #3
0
파일: fs.cpp 프로젝트: e-learning/aptu-os
void FS::format(){
    if (!initialized) {throw "Not initialized";}
    meta.block_map_size = config.block_no/8 + 1;
    meta.block_map = new char[meta.block_map_size];
    memset(meta.block_map, 0, sizeof(char)*meta.block_map_size);
    int free_space_size = config.block_size - sizeof(BlockDescriptor);
    int no_of_blocks = (sizeof(meta) + meta.block_map_size)/free_space_size + 1;
    meta.root_block = no_of_blocks;
    for(int i = 0; i<no_of_blocks; ++i) reserve_block(i);

    FileDescriptor root;
    root.set_filename("/");
    root.first_block = meta.root_block;
    write_data(&root, sizeof(FileDescriptor), 0);

    write_meta();
}
예제 #4
0
파일: fs.cpp 프로젝트: e-learning/aptu-os
FileDescriptor FS::get_file(std::string path, bool create, bool file_available){

	if( path[path.size() - 1] != '/' ){
		path.push_back('/');
	}

	int pos;
	pos = path.find('/');
	if (pos != 0){ throw std::runtime_error("Bad path"); }
	path.erase(0, 1);

	FileDescriptor curr_dir;
	Block * curr_dir_block = new Block(meta.root_block, config.block_size, _root);
	read_data(&curr_dir, sizeof(curr_dir), curr_dir_block);

	while(path.size() != 0){
		pos = path.find('/');
		std::string dir_name = path.substr(0, pos);

		bool found = false;
		for(auto it = DirIterator(*this, curr_dir); it != DirIterator(*this); ++it){
			FileDescriptor file = *it;
			if(std::string(file.filename) == dir_name){
				found = true;
				if(!file.directory){
					if(file_available && pos == (int)path.size() - 1){
						return file;
					}else{
						throw std::runtime_error("File in path");
					}
				}
				curr_dir = file;
			}
		}
		if(!found){
			if( create ){
				Block * dir_block = get_free_block();
				FileDescriptor dir;
				dir.set_filename(dir_name);
				dir.first_block = dir_block->get_index();
				dir.parent_file = curr_dir.first_block;
				if( curr_dir.first_child == -1 ){
					curr_dir.first_child = dir.first_block;
				} else{
					Block * neighbour_file_block = new Block(curr_dir.first_child, config.block_size, _root);
					curr_dir.first_child = dir.first_block;
					FileDescriptor neighbour_file_descriptor;
					read_data(&neighbour_file_descriptor, sizeof(FileDescriptor), neighbour_file_block);
					dir.next_file = neighbour_file_descriptor.first_block;
					neighbour_file_descriptor.prev_file = dir.first_block;
					update_descriptor(neighbour_file_descriptor, neighbour_file_block);
				}
				update_descriptor(curr_dir, curr_dir_block);
				curr_dir = dir;

				write_data(&dir, sizeof(FileDescriptor), dir_block);
			} else{
				throw std::runtime_error("No such file or directory");
			}
		}

		curr_dir_block = new Block(curr_dir.first_block, config.block_size, _root);
		path.erase(0, pos + 1);
	}
	return curr_dir;
}