diff --git a/src/filesys/filesys.rs b/src/filesys/filesys.rs index 3130ceb..fe53f35 100644 --- a/src/filesys/filesys.rs +++ b/src/filesys/filesys.rs @@ -1,6 +1,103 @@ +use super::directory; +pub const DIRECTORY_SECTOR: i32 = 1; + +/// decompose the name of the first directory +/// of the path given in argument, as well as the remainder of the path. +/// if we call decompname("/bin/new/halt", head, tail), we get "bin" in head and "/new/halt" in tail +/// returns true if everything goes ok, otherwise, return false. +/// head and tail MUST be large enough to contain the resulting strings +/// +/// ### parameters +/// +/// - **orig_path** the pathname we want to decompose +/// - **head** the first element in the path (for instance "bin") +/// - **tail** the remainder of the string (for instance "/new/halt") +pub fn decomp_name(origin_path: String, head: &mut String, tail: &mut String) -> bool { + let mut working_path = origin_path; + + // remove the leading "/" if any + if working_path.get(0..1).unwrap_or_else(|| "").eq("/") { + working_path = (&working_path[1..]).to_string(); + } + + if working_path.contains("/") { + let index = working_path.find("/").expect("shouldn't happen"); + *head = working_path[..index].to_string(); + *tail = working_path[index..].to_string(); + return true; + } else { + *head = "".to_string(); + *tail = origin_path; + return false; + } +} + +/// this function takes a complete pathname and returns +/// the disc sector of the fileheader of the directory. +/// return -1 in case of error +/// +/// IMPORTANT WARNING : name is modified : after the execution, name +/// contains only the name of the file +/// (e.g. if we called find_dir("/bin/halt") then name is "halt" after the execution, +/// the function returns the sector number of the directory "/bin"). +/// +/// Actually, this function does not support complete pathnames +/// This is one of the objectives of the file system assignment +/// +/// ### parameters +/// +/// - **name** is the complete name (relatively to the root directory). +/// its content will be modified! +pub fn find_dir(name: &mut String) -> i32 { + let directory = directory::init_directory(config.num_dir_entries); + directory.fetch_from(filesys::get_dir_file()); + + let mut sector = DIRECTORY_SECTOR; + let mut dirname = String::from(""); + let mut reminder = String::from(""); + + while decomp_name(name.to_string(), &mut dirname, &mut reminder) { + *name = reminder; + + // Get the sector of the file/directory corresponding to 'name' + sector = directory.find(dirname); + if sector < 0 { + return -1; // This file/directory does not exist + } + + let file = openfile::init_open_file(sector); + if file.get_file_header().is_dir() { + directory.fetch_from(&file); + } else { + return -1; + } + } + *name = reminder; + + sector +} pub struct Filesys { - pub free_map_file : Open_File, //Bit map of free disk blocks, represented as a file - pub directory_file : Open_file //"Root" directory -- list of file names, represented as a file -} \ No newline at end of file + pub free_map_file: Open_file, //Bit map of free disk blocks, represented as a file + pub directory_file: Open_file, //"Root" directory -- list of file names, represented as a file +} + +impl Filesys { + /// Initialize the file system. + /// If format = true, the disk has nothing on it, + /// and we need to initialize the disk to contain an empty directory, + /// and a bitmap of free sectors (with almost but not all of the sectors marked as free). + /// + /// If format = false, we just have to open the files + /// representing the bitmap and the directory. + /// + /// ### parameters + /// + /// - **format** should we initialize the disk? + pub fn init_filesys(format: bool) -> Filesys { + if format { + let free_map = bitmap::init_bitmap(); + } + } +} diff --git a/src/filesys/fsmisc.rs b/src/filesys/fsmisc.rs index ab6ec4e..aed3fdb 100644 --- a/src/filesys/fsmisc.rs +++ b/src/filesys/fsmisc.rs @@ -1,19 +1,23 @@ -use std::{fs::File, io::{Seek, SeekFrom, Read}}; +use std::{ + fs::File, + io::{Read, Seek, SeekFrom}, +}; use super::filesys; pub const TRANSFER_SIZE: usize = 10; /// copy the contents of the UNIX file "from" to the Nachos file "to" -/// +/// /// `panic!` when the file from doesn't exist -/// +/// +/// ### parameters +/// /// - **from** file UNIX /// - **to** BurritOS file -pub fn copy(from : &str, to : &str) { - +pub fn copy(from: &str, to: &str) { let file_from_opt = File::options().read(true).open(from); - let mut file_from : File; + let mut file_from: File; match file_from_opt { Err(e) => { panic!("Copy: couldn't open Unix file {}", from); @@ -35,7 +39,9 @@ pub fn copy(from : &str, to : &str) { let mut buffer = [0; TRANSFER_SIZE]; loop { - let amount_read = file_from.read(&mut buffer).expect("copy : couldn't read the UNIX file"); + let amount_read = file_from + .read(&mut buffer) + .expect("copy : couldn't read the UNIX file"); open_file.write(&buffer[..amount_read]); if amount_read != TRANSFER_SIZE { @@ -45,11 +51,13 @@ pub fn copy(from : &str, to : &str) { } /// Print the contents of the Nachos file "name". -/// +/// /// `panic!` when the file name doewn't exist -/// +/// +/// ### parameters +/// /// - **name** of the BurritOS file -pub fn print(name : &str) { +pub fn print(name: &str) { let open_file = filesys::open(name); let mut buffer = [0; TRANSFER_SIZE]; @@ -63,4 +71,4 @@ pub fn print(name : &str) { break; } } -} \ No newline at end of file +} diff --git a/src/filesys/mod.rs b/src/filesys/mod.rs index 194865c..e9cb30b 100644 --- a/src/filesys/mod.rs +++ b/src/filesys/mod.rs @@ -1,2 +1,3 @@ +pub mod directory; +pub mod filesys; pub mod fsmisc; -pub mod filesys; \ No newline at end of file