diff --git a/Cargo.toml b/Cargo.toml index c64817d..8c256d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,13 +4,18 @@ version = "0.0.1" authors = ["WangRunji "] [lib] +name = "lib" #crate-type = ["staticlib"] +[[bin]] +name = "mksfs" +path = "src/bin/mksfs.rs" +required-features = ["std"] + [profile.dev] panic = 'abort' # prevent `_Unwind_Resume` link error [dependencies] -spin = "0.4" bit-set = { default-features = false, version = "0.5" } # default-features contains 'std' static_assertions = "0.2.5" @@ -19,4 +24,5 @@ bitflags = "1.0" [features] debug_print = [] -ucore = [] \ No newline at end of file +ucore = [] +std = [] \ No newline at end of file diff --git a/src/bin/mksfs.rs b/src/bin/mksfs.rs new file mode 100644 index 0000000..17dc102 --- /dev/null +++ b/src/bin/mksfs.rs @@ -0,0 +1,61 @@ +extern crate lib; + +use std::env; +use std::fs; +use std::io::Read; +use std::path::Path; +use lib::*; + +fn main () { + println!("USAGE: "); + let args: Vec<_> = env::args().collect(); + let cmd = &args[1]; + let dir_path = Path::new(&args[2]); + let img_path = Path::new(&args[3]); + match cmd.as_str() { + "zip" => zip(dir_path, img_path), + "unzip" => unzip(dir_path, img_path), + _ => panic!("Invalid command: {}", cmd), + } +} + +fn zip(path: &Path, img_path: &Path) { + use lib::std_impl; + + let mut img = fs::File::create(img_path) + .expect(format!("Failed to create file: {:?}", img_path).as_str()); + let sfs = SimpleFileSystem::create(Box::new(img), 0x1000000); + let inode = sfs.root_inode(); + zip_dir(path, inode); +} + +fn zip_dir(path: &Path, inode: INodePtr) { + println!("{:?}", path); + let dir = fs::read_dir(path).expect("Failed to open dir"); + for entry in dir { + let entry = entry.unwrap(); + let name_ = entry.file_name(); + let name = name_.to_str().unwrap(); + let type_ = entry.file_type().unwrap(); + if type_.is_file() { + let inode = inode.borrow_mut().create(name, FileType::File) + .expect("Failed to create INode"); + let mut file = fs::File::open(entry.path()) + .expect("Failed to open file"); + let mut buf = Vec::::new(); + file.read_to_end(&mut buf) + .expect("Failed to read file"); + inode.borrow_mut().write_at(0, buf.as_ref()) + .expect("Failed to write image"); + println!("{:?}", entry.path()); + } else if type_.is_dir() { + let inode = inode.borrow_mut().create(name, FileType::Dir) + .expect("Failed to create INode"); + zip_dir(entry.path().as_path(), inode); + } + } +} + +fn unzip(path: &Path, img_path: &Path) { + +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index ffef679..2a504cd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,10 +3,9 @@ #![cfg_attr(feature = "ucore", feature(allocator_api, global_allocator, lang_items))] #![no_std] -#[cfg(test)] +#[cfg(any(test, feature = "std"))] #[macro_use] extern crate std; -extern crate spin; #[macro_use] extern crate alloc; extern crate bit_set; @@ -37,4 +36,29 @@ pub use vfs::*; #[cfg(feature = "ucore")] #[global_allocator] -pub static UCORE_ALLOCATOR: c_interface::UcoreAllocator = c_interface::UcoreAllocator{}; \ No newline at end of file +pub static UCORE_ALLOCATOR: c_interface::UcoreAllocator = c_interface::UcoreAllocator{}; + +#[cfg(any(test, feature = "std"))] +pub mod std_impl { + use std::fs::{File, OpenOptions}; + use std::io::{Read, Write, Seek, SeekFrom}; + use super::Device; + + impl Device for File { + fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option { + let offset = offset as u64; + match self.seek(SeekFrom::Start(offset)) { + Ok(real_offset) if real_offset == offset => self.read(buf).ok(), + _ => None, + } + } + + fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option { + let offset = offset as u64; + match self.seek(SeekFrom::Start(offset)) { + Ok(real_offset) if real_offset == offset => self.write(buf).ok(), + _ => None, + } + } + } +} \ No newline at end of file diff --git a/src/sfs.rs b/src/sfs.rs index cbf7c89..dddabef 100644 --- a/src/sfs.rs +++ b/src/sfs.rs @@ -1,4 +1,3 @@ -use spin::Mutex; use bit_set::BitSet; use alloc::{boxed::Box, Vec, BTreeMap, rc::{Rc, Weak}, String}; use core::cell::{RefCell, RefMut}; diff --git a/src/tests.rs b/src/tests.rs index ce19b5a..3772d12 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -8,24 +8,6 @@ use std::rc::Rc; use std::mem::uninitialized; use super::structs::{DiskEntry, AsBuf}; -impl Device for File { - fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option { - let offset = offset as u64; - match self.seek(SeekFrom::Start(offset)) { - Ok(real_offset) if real_offset == offset => self.read(buf).ok(), - _ => None, - } - } - - fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option { - let offset = offset as u64; - match self.seek(SeekFrom::Start(offset)) { - Ok(real_offset) if real_offset == offset => self.write(buf).ok(), - _ => None, - } - } -} - fn _open_sample_file() -> Rc { let file = File::open("sfs.img") .expect("failed to open sfs.img");