diff --git a/.gitignore b/.gitignore index 54a3b4d18a..8d5dd60102 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,4 @@ -# Compiled files -*.o -*.so -*.rlib -*.dll - -# Executables -*.exe - -# Generated by Cargo Cargo.lock -/target/ - -# Images -*.bin +target +image.bin +image diff --git a/Cargo.toml b/Cargo.toml index ec5570ab57..10ba4c9ddd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "redoxfs" description = "The Redox Filesystem" repository = "https://github.com/redox-os/redoxfs" -version = "0.1.0" +version = "0.1.1" license-file = "LICENSE" readme = "README.md" authors = ["Jeremy Soller "] @@ -13,15 +13,11 @@ path = "src/lib.rs" [[bin]] name = "redoxfs" -path = "scheme/main.rs" +path = "mount/main.rs" [[bin]] -name = "redoxfs-fuse" -path = "fuse/main.rs" - -[[bin]] -name = "redoxfs-utility" -path = "utility/main.rs" +name = "redoxfs-mkfs" +path = "mkfs/main.rs" [dependencies] spin = "*" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..0e233fd974 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +image.bin: + dd if=/dev/zero of=image.bin bs=1M count=1024 + cargo build --release --bin redoxfs-mkfs + target/release/redoxfs-mkfs image.bin + +mount: image.bin FORCE + mkdir -p image + cargo build --release --bin redoxfs + target/release/redoxfs image.bin image + +unmount: FORCE + sync + -fusermount -u image + rm -rf image + +clean: FORCE + sync + -fusermount -u image + rm -rf image image.bin + cargo clean + +FORCE: diff --git a/create.sh b/create.sh deleted file mode 100755 index f31912ffd3..0000000000 --- a/create.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -rm -f test.bin - -cargo run --bin redoxfs-utility test.bin << "EOF" - -mk a_file -mkdir a_directory -cd a_directory - -ed b_file -B FILE -. - -cat b_file - -ed c_file -C FILE -. - -cat c_file - -ls - -exit - -EOF diff --git a/scheme/image.rs b/mkfs/image.rs similarity index 90% rename from scheme/image.rs rename to mkfs/image.rs index b589c5cb69..f6ac3acd07 100644 --- a/scheme/image.rs +++ b/mkfs/image.rs @@ -1,8 +1,7 @@ -use std::fs::File; +use std::fs::{File, OpenOptions}; use std::io::{Read, Write, Seek, SeekFrom}; use redoxfs::Disk; - use syscall::error::{Error, Result, EIO}; macro_rules! try_disk { @@ -21,7 +20,7 @@ pub struct Image { impl Image { pub fn open(path: &str) -> Result { - let file = try_disk!(File::open(path)); + let file = try_disk!(OpenOptions::new().read(true).write(true).open(path)); Ok(Image { file: file }) @@ -30,7 +29,6 @@ impl Image { impl Disk for Image { fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result { - // println!("Image read at {}", block); try_disk!(self.file.seek(SeekFrom::Start(block * 512))); let count = try_disk!(self.file.read(buffer)); Ok(count) diff --git a/mkfs/main.rs b/mkfs/main.rs new file mode 100644 index 0000000000..1a02b536a3 --- /dev/null +++ b/mkfs/main.rs @@ -0,0 +1,31 @@ +#![deny(warnings)] + +extern crate redoxfs; +extern crate syscall; + +use std::env; +use std::str; + +use redoxfs::FileSystem; + +use image::Image; + +pub mod image; + +fn main() { + let mut args = env::args(); + if let Some(path) = args.nth(1) { + //Open an existing image + match Image::open(&path) { + Ok(disk) => match FileSystem::create(Box::new(disk)) { + Ok(filesystem) => { + println!("redoxfs: created filesystem on {}, size {} MB", path, filesystem.header.1.size/1024/1024); + }, + Err(err) => println!("redoxfs: failed to create filesystem on {}: {}", path, err) + }, + Err(err) => println!("redoxfs: failed to open image {}: {}", path, err) + } + } else { + println!("redoxfs: no disk image provided"); + } +} diff --git a/mount.sh b/mount.sh deleted file mode 100755 index 15b1ac3510..0000000000 --- a/mount.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -mkdir -p test - -cargo run --bin redoxfs-fuse test.bin test & diff --git a/scheme/cache/linked_hash_map.rs b/mount/cache/linked_hash_map.rs similarity index 100% rename from scheme/cache/linked_hash_map.rs rename to mount/cache/linked_hash_map.rs diff --git a/scheme/cache/lru_cache.rs b/mount/cache/lru_cache.rs similarity index 100% rename from scheme/cache/lru_cache.rs rename to mount/cache/lru_cache.rs diff --git a/scheme/cache/mod.rs b/mount/cache/mod.rs similarity index 100% rename from scheme/cache/mod.rs rename to mount/cache/mod.rs diff --git a/fuse/main.rs b/mount/fuse.rs similarity index 75% rename from fuse/main.rs rename to mount/fuse.rs index 528724128c..9b6f3fd503 100644 --- a/fuse/main.rs +++ b/mount/fuse.rs @@ -1,24 +1,20 @@ -#![deny(warnings)] - extern crate fuse; -extern crate redoxfs; -extern crate syscall; extern crate time; -use image::Image; -use std::env; +use redoxfs; use std::path::Path; -use time::Timespec; -use fuse::{FileType, FileAttr, Filesystem, Request, ReplyData, ReplyEntry, ReplyAttr, ReplyCreate, ReplyDirectory, ReplyEmpty, ReplyStatfs, ReplyWrite}; -pub mod image; +use self::fuse::{FileType, FileAttr, Filesystem, Request, ReplyData, ReplyEntry, ReplyAttr, ReplyCreate, ReplyDirectory, ReplyEmpty, ReplyStatfs, ReplyWrite}; +use self::time::Timespec; + +pub use self::fuse::mount; const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; // 1 second const CREATE_TIME: Timespec = Timespec { sec: 0, nsec: 0 }; -struct RedoxFS { - fs: redoxfs::FileSystem, +pub struct Fuse { + pub fs: redoxfs::FileSystem, } fn node_attr(node: &(u64, redoxfs::Node)) -> FileAttr { @@ -44,7 +40,7 @@ fn node_attr(node: &(u64, redoxfs::Node)) -> FileAttr { } } -impl Filesystem for RedoxFS { +impl Filesystem for Fuse { fn lookup(&mut self, _req: &Request, parent_block: u64, name: &Path, reply: ReplyEntry) { match self.fs.find_node(name.to_str().unwrap(), parent_block) { Ok(node) => { @@ -257,64 +253,3 @@ impl Filesystem for RedoxFS { } } } - -#[cfg(target_os = "macos")] -fn main() { - use std::ffi::OsStr; - - if let Some(path) = env::args().nth(1) { - //Open an existing image - match Image::open(&path) { - Ok(disk) => match redoxfs::FileSystem::open(Box::new(disk)) { - Ok(filesystem) => { - println!("redoxfs: opened filesystem {}", path); - - if let Some(mountpoint) = env::args_os().nth(2) { - fuse::mount(RedoxFS { - fs: filesystem - }, &mountpoint, &[ - // One of the uses of this redoxfs fuse wrapper is to populate a filesystem - // while building the Redox OS kernel. This means that we need to write on - // a filesystem that belongs to `root`, which in turn means that we need to - // be `root`, thus that we need to allow `root` to have access. - OsStr::new("-o"), - OsStr::new("defer_permissions"), - ]); - } else { - println!("redoxfs: no mount point provided"); - } - }, - Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err) - }, - Err(err) => println!("redoxfs: failed to open image {}: {}", path, err) - } - } else { - println!("redoxfs: no disk image provided"); - } -} - -#[cfg(not(target_os = "macos"))] -fn main() { - if let Some(path) = env::args().nth(1) { - //Open an existing image - match Image::open(&path) { - Ok(disk) => match redoxfs::FileSystem::open(Box::new(disk)) { - Ok(filesystem) => { - println!("redoxfs: opened filesystem {}", path); - - if let Some(mountpoint) = env::args_os().nth(2) { - fuse::mount(RedoxFS { - fs: filesystem - }, &mountpoint, &[]); - } else { - println!("redoxfs: no mount point provided"); - } - }, - Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err) - }, - Err(err) => println!("redoxfs: failed to open image {}: {}", path, err) - } - } else { - println!("redoxfs: no disk image provided"); - } -} diff --git a/fuse/image.rs b/mount/image.rs similarity index 100% rename from fuse/image.rs rename to mount/image.rs diff --git a/mount/main.rs b/mount/main.rs new file mode 100644 index 0000000000..11bdd88242 --- /dev/null +++ b/mount/main.rs @@ -0,0 +1,134 @@ +#![deny(warnings)] +#![cfg_attr(unix, feature(libc))] + +#[cfg(unix)] +extern crate libc; + +extern crate redoxfs; +extern crate syscall; + +use std::env; +use std::fs::File; +use std::os::unix::io::FromRawFd; +use std::path::Path; +use std::process; + +use cache::Cache; +use image::Image; + +pub mod cache; +pub mod image; + +#[cfg(unix)] +pub mod fuse; + +#[cfg(target_os = "redox")] +pub mod redox; + +#[cfg(unix)] +fn fork() -> isize { + unsafe { libc::fork() as isize } +} + +#[cfg(unix)] +fn pipe(pipes: &mut [i32; 2]) -> isize { + unsafe { libc::pipe2(pipes.as_mut_ptr(), 0) as isize } +} + +#[cfg(all(unix, target_os = "macos"))] +fn mount>(filesystem: redoxfs::FileSystem, mountpoint: &P, mut write: File) { + use std::io::Write; + + let _ = write.write(&[0]); + drop(write); + + fuse::mount(fuse::Fuse { + fs: filesystem + }, mountpoint, &[ + // One of the uses of this redoxfs fuse wrapper is to populate a filesystem + // while building the Redox OS kernel. This means that we need to write on + // a filesystem that belongs to `root`, which in turn means that we need to + // be `root`, thus that we need to allow `root` to have access. + OsStr::new("-o"), + OsStr::new("defer_permissions"), + ]); +} + +#[cfg(all(unix, not(target_os = "macos")))] +fn mount>(filesystem: redoxfs::FileSystem, mountpoint: &P, mut write: File) { + use std::io::Write; + + let _ = write.write(&[0]); + drop(write); + + fuse::mount(fuse::Fuse { + fs: filesystem + }, mountpoint, &[]); +} + +#[cfg(target_os = "redox")] +fn fork() -> isize { + unsafe { syscall::Error::mux(syscall::clone(0)) as isize } +} + +#[cfg(target_os = "redox")] +fn pipe(pipes: &mut [usize; 2]) -> isize { + syscall::Error::mux(syscall::pipe2(pipes, 0)) as isize +} + +#[cfg(target_os = "redox")] +fn mount>(filesystem: redoxfs::FileSystem, mountpoint: &P, write: File) { + redox::mount(filesystem, mountpoint, write); +} + +fn main() { + use std::io::{Read, Write}; + + let mut pipes = [0; 2]; + if pipe(&mut pipes) == 0 { + let mut read = unsafe { File::from_raw_fd(pipes[0]) }; + let mut write = unsafe { File::from_raw_fd(pipes[1]) }; + + let pid = fork(); + if pid == 0 { + drop(read); + + if let Some(path) = env::args().nth(1) { + //Open an existing image + match Image::open(&path).map(|image| Cache::new(image)) { + Ok(disk) => match redoxfs::FileSystem::open(Box::new(disk)) { + Ok(filesystem) => { + println!("redoxfs: opened filesystem {}", path); + + if let Some(mountpoint) = env::args_os().nth(2) { + mount(filesystem, &mountpoint, write); + process::exit(0); + } else { + println!("redoxfs: no mount point provided"); + } + }, + Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err) + }, + Err(err) => println!("redoxfs: failed to open image {}: {}", path, err) + } + + let _ = write.write(&[1]); + drop(write); + process::exit(1); + } else { + println!("redoxfs: no disk image provided"); + } + } else if pid > 0 { + drop(write); + + let mut res = [0]; + read.read(&mut res).unwrap(); + + process::exit(res[0] as i32); + } else { + panic!("redoxfs: failed to fork"); + } + } else { + panic!("redoxfs: failed to create pipe"); + } +} diff --git a/mount/redox/mod.rs b/mount/redox/mod.rs new file mode 100644 index 0000000000..371a49149d --- /dev/null +++ b/mount/redox/mod.rs @@ -0,0 +1,33 @@ +extern crate spin; + +use redoxfs; +use syscall::{Packet, Scheme}; +use std::fs::File; +use std::io::{Read, Write}; +use std::path::Path; + +use self::scheme::FileScheme; + +pub mod resource; +pub mod scheme; + +pub fn mount>(filesystem: redoxfs::FileSystem, mountpoint: &P, mut write: File) { + let mountpoint = mountpoint.as_ref(); + match File::create(format!(":{}", mountpoint.display())) { + Ok(mut socket) => { + println!("redoxfs: mounted filesystem on {}:", mountpoint.display()); + + let _ = write.write(&[0]); + drop(write); + + let scheme = FileScheme::new(format!("{}", mountpoint.display()), filesystem); + loop { + let mut packet = Packet::default(); + socket.read(&mut packet).unwrap(); + scheme.handle(&mut packet); + socket.write(&packet).unwrap(); + } + }, + Err(err) => println!("redoxfs: failed to create {} scheme: {}", mountpoint.display(), err) + } +} diff --git a/scheme/resource.rs b/mount/redox/resource.rs similarity index 100% rename from scheme/resource.rs rename to mount/redox/resource.rs diff --git a/scheme/scheme.rs b/mount/redox/scheme.rs similarity index 98% rename from scheme/scheme.rs rename to mount/redox/scheme.rs index 48f67b6ae9..6886c4d89e 100644 --- a/scheme/scheme.rs +++ b/mount/redox/scheme.rs @@ -1,7 +1,7 @@ -use resource::{Resource, DirResource, FileResource}; +use redox::resource::{Resource, DirResource, FileResource}; +use redox::spin::Mutex; use redoxfs::{FileSystem, Node}; -use spin::Mutex; use std::cell::RefCell; use std::collections::BTreeMap; use std::str; @@ -13,14 +13,14 @@ use syscall::flag::{O_CREAT, O_DIRECTORY, O_STAT, O_EXCL, O_TRUNC, O_ACCMODE, O_ use syscall::scheme::Scheme; pub struct FileScheme { - name: &'static str, + name: String, fs: RefCell, next_id: AtomicUsize, files: Mutex>> } impl FileScheme { - pub fn new(name: &'static str, fs: FileSystem) -> FileScheme { + pub fn new(name: String, fs: FileSystem) -> FileScheme { FileScheme { name: name, fs: RefCell::new(fs), diff --git a/scheme/main.rs b/scheme/main.rs deleted file mode 100644 index 25af9eebc3..0000000000 --- a/scheme/main.rs +++ /dev/null @@ -1,72 +0,0 @@ -#![deny(warnings)] - -extern crate redoxfs; -extern crate spin; -extern crate syscall; - -use std::{env, process}; -use std::fs::File; -use std::io::{Read, Write}; - -use cache::Cache; -use image::Image; -use scheme::FileScheme; - -use redoxfs::FileSystem; - -use syscall::{Packet, Scheme}; - -pub mod cache; -pub mod image; -pub mod resource; -pub mod scheme; - -fn main() { - if let Some(path) = env::args().nth(1) { - let mut pipes = [0; 2]; - syscall::pipe2(&mut pipes, 0).unwrap(); - - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - let _ = syscall::close(pipes[0]); - - match Image::open(&path).map(|image| Cache::new(image)) { - Ok(disk) => match FileSystem::open(Box::new(disk)) { - Ok(fs) => match File::create(":file") { - Ok(mut socket) => { - println!("redoxfs: mounted filesystem {} on file:", path); - - let _ = syscall::write(pipes[1], &[1]); - - let scheme = FileScheme::new("file", fs); - loop { - let mut packet = Packet::default(); - socket.read(&mut packet).unwrap(); - scheme.handle(&mut packet); - socket.write(&packet).unwrap(); - } - }, - Err(err) => println!("redoxfs: failed to create file scheme: {}", err) - }, - Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err) - }, - Err(err) => println!("redoxfs: failed to open image {}: {}", path, err) - } - - let _ = syscall::write(pipes[1], &[0]); - - let _ = syscall::close(pipes[1]); - } else { - let _ = syscall::close(pipes[1]); - - let mut res = [0]; - syscall::read(pipes[0], &mut res).unwrap(); - - let _ = syscall::close(pipes[0]); - - process::exit(res[0] as i32); - } - } else { - println!("redoxfs: no disk image provided"); - } -} diff --git a/umount.sh b/umount.sh deleted file mode 100755 index 6998019789..0000000000 --- a/umount.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -fusermount -u test diff --git a/utility/image.rs b/utility/image.rs deleted file mode 100644 index cb1356aadb..0000000000 --- a/utility/image.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std::fs::{File, OpenOptions}; -use std::io::{Read, Write, Seek, SeekFrom}; - -use redoxfs::Disk; -use syscall::error::{Error, Result, EIO}; - -macro_rules! try_disk { - ($expr:expr) => (match $expr { - Ok(val) => val, - Err(err) => { - println!("Disk I/O Error: {}", err); - return Err(Error::new(EIO)); - } - }) -} - -pub struct Image { - file: File -} - -impl Image { - pub fn open(path: &str) -> Result { - let file = try_disk!(OpenOptions::new().read(true).write(true).open(path)); - Ok(Image { - file: file - }) - } - - pub fn create(path: &str, size: u64) -> Result { - let file = try_disk!(OpenOptions::new().read(true).write(true).create(true).open(path)); - try_disk!(file.set_len(size)); - Ok(Image { - file: file - }) - } -} - -impl Disk for Image { - fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result { - try_disk!(self.file.seek(SeekFrom::Start(block * 512))); - let count = try_disk!(self.file.read(buffer)); - Ok(count) - } - - fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result { - try_disk!(self.file.seek(SeekFrom::Start(block * 512))); - let count = try_disk!(self.file.write(buffer)); - Ok(count) - } - - fn size(&mut self) -> Result { - let size = try_disk!(self.file.seek(SeekFrom::End(0))); - Ok(size) - } -} diff --git a/utility/main.rs b/utility/main.rs deleted file mode 100644 index 3331893981..0000000000 --- a/utility/main.rs +++ /dev/null @@ -1,238 +0,0 @@ -#![deny(warnings)] - -extern crate redoxfs; -extern crate syscall; - -use std::env; -use std::io::{self, Write}; -use std::path::Path; -use std::str; - -use redoxfs::{FileSystem, Node}; - -use image::Image; - -pub mod image; - -fn shell(mut fs: FileSystem){ - let mut block = fs.header.1.root; - - let mut stdout = io::stdout(); - let stdin = io::stdin(); - - loop { - stdout.write(b"redoxfs# ").unwrap(); - stdout.flush().unwrap(); - - let mut line = String::new(); - stdin.read_line(&mut line).unwrap(); - - let mut args = line.trim().split(' '); - if let Some(command) = args.next() { - match command { - "" => (), - "exit" => break, - "header" => println!("{:#?}", fs.header), - "node" => { - if let Some(arg) = args.next() { - match arg.parse::() { - Ok(block) => match fs.node(block) { - Ok(node) => println!("{}: {:#?}", node.0, node.1), - Err(err) => println!("node: failed to read {}: {}", block, err) - }, - Err(err) => println!("node: invalid block {}: {}", arg, err) - } - } else { - println!("node "); - } - }, - "root" => { - let block = fs.header.1.root; - match fs.node(block) { - Ok(node) => println!("{}: {:#?}", node.0, node.1), - Err(err) => println!("node: failed to read {}: {}", block, err) - } - }, - "free" => { - let block = fs.header.1.free; - match fs.node(block) { - Ok(node) => println!("{}: {:#?}", node.0, node.1), - Err(err) => println!("node: failed to read {}: {}", block, err) - } - }, - "cat" => { - if let Some(arg) = args.next() { - match fs.find_node(arg, block) { - Ok(node) => { - println!("{}: {:#?}", node.0, node.1); - - let mut data = [0; 512]; - match fs.read_node(node.0, 0, &mut data) { - Ok(count) => println!("cat: read {} bytes\n{}", count, unsafe { str::from_utf8_unchecked(&data) }), - Err(err) => println!("cat: failed to read {}: {}", node.0, err) - } - } - Err(err) => println!("cat: failed to create {}: {}", arg, err) - } - } else { - println!("cat "); - } - }, - "cd" => { - if let Some(arg) = args.next() { - if arg == "." { - - } else if arg == ".." { - match fs.node(block) { - Ok(node) => if node.1.parent > 0 { - block = node.1.parent; - println!("cd: {}", block); - } else { - println!("cd: no parent directory {}", block); - }, - Err(err) => println!("cd: failed to read {}: {}", block, err) - } - } else { - match fs.find_node(arg, block) { - Ok(node) => if node.1.is_dir() { - block = node.0; - println!("cd: {}", block); - } else { - println!("cd: not a dir {}", arg); - }, - Err(err) => println!("cd: failed to read {}: {}", arg, err) - } - } - } else { - println!("cd "); - } - }, - "ed" => { - if let Some(arg) = args.next() { - match fs.create_node(Node::MODE_FILE, arg, block) { - Ok(node) => { - println!("{}: {:#?}", node.0, node.1); - - let mut data = String::new(); - loop { - let mut line = String::new(); - stdin.read_line(&mut line).unwrap(); - - if line.is_empty() || line == ".\n" { - break; - } else { - data.push_str(&line); - } - } - println!("{}:\n{}", arg, data); - - match fs.write_node(node.0, 0, &data.as_bytes()) { - Ok(count) => println!("ed: wrote {} bytes", count), - Err(err) => println!("ed: failed to write {}: {}", node.0, err) - } - } - Err(err) => println!("ed: failed to create {}: {}", arg, err) - } - } else { - println!("ed "); - } - }, - "find" => { - if let Some(arg) = args.next() { - match fs.find_node(arg, block) { - Ok(node) => println!("{}: {:#?}", node.0, node.1), - Err(err) => println!("find: failed to read {}: {}", arg, err) - } - } else { - println!("find "); - } - }, - "ls" => { - let mut children = Vec::new(); - match fs.child_nodes(&mut children, block) { - Ok(()) => for node in children.iter() { - println!("{}: {:#?}", node.0, node.1); - }, - Err(err) => println!("ls: failed to read {}: {}", block, err) - } - }, - "mk" => { - if let Some(arg) = args.next() { - match fs.create_node(Node::MODE_FILE, arg, block) { - Ok(node) => println!("{}: {:#?}", node.0, node.1), - Err(err) => println!("mk: failed to create {}: {}", arg, err) - } - } else { - println!("mk "); - } - }, - "mkdir" => { - if let Some(arg) = args.next() { - match fs.create_node(Node::MODE_DIR, arg, block) { - Ok(node) => println!("{}: {:#?}", node.0, node.1), - Err(err) => println!("mkdir: failed to create {}: {}", arg, err) - } - } else { - println!("mkdir "); - } - }, - "rm" => { - if let Some(arg) = args.next() { - match fs.remove_node(Node::MODE_FILE, arg, block) { - Ok(()) => println!("rm {}", arg), - Err(err) => println!("rm: failed to remove {}: {}", arg, err) - } - } else { - println!("rm "); - } - }, - "rmdir" => { - if let Some(arg) = args.next() { - match fs.remove_node(Node::MODE_DIR, arg, block) { - Ok(()) => println!("rmdir {}", arg), - Err(err) => println!("rmdir: failed to remove {}: {}", arg, err) - } - } else { - println!("rmdir "); - } - }, - _ => println!("commands: exit header node root free cat ed find ls mk mkdir rm rmdir") - } - } - } -} - -fn main() { - let mut args = env::args(); - if let Some(path) = args.nth(1) { - if Path::new(&path).exists() { - //Open an existing image - match Image::open(&path) { - Ok(disk) => match FileSystem::open(Box::new(disk)) { - Ok(filesystem) => { - println!("redoxfs: opened filesystem {}", path); - shell(filesystem); - }, - Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err) - }, - Err(err) => println!("redoxfs: failed to open image {}: {}", path, err) - } - }else if let Some(size_str) = args.next() { - let size = size_str.parse::().expect("redoxfs: size is not a valid number") * 1024 * 1024; - match Image::create(&path, size) { - Ok(disk) => match FileSystem::create(Box::new(disk)) { - Ok(filesystem) => { - println!("redoxfs: created filesystem {}", path); - shell(filesystem); - }, - Err(err) => println!("redoxfs: failed to create filesystem {}: {}", path, err) - }, - Err(err) => println!("redoxfs: failed to create image {}: {}", path, err) - } - } else { - println!("redoxfs: no size provided"); - } - } else { - println!("redoxfs: no disk image provided"); - } -}