Skip to content

Commit

Permalink
Add UUID matching
Browse files Browse the repository at this point in the history
  • Loading branch information
jackpot51 committed Oct 1, 2017
1 parent db22937 commit e74975d
Showing 1 changed file with 157 additions and 38 deletions.
195 changes: 157 additions & 38 deletions src/bin/mount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ extern crate libc;
extern crate syscall;

extern crate redoxfs;
extern crate uuid;

use std::env;
use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::FromRawFd;
use std::process;

use redoxfs::{DiskCache, DiskFile, mount};
use uuid::Uuid;

#[cfg(unix)]
fn fork() -> isize {
Expand All @@ -37,56 +40,172 @@ fn pipe(pipes: &mut [usize; 2]) -> isize {
}

fn usage() {
println!("redoxfs [disk] [mountpoint]");
println!("redoxfs [--uuid] [disk or uuid] [mountpoint]");
}

enum DiskId {
Path(String),
Uuid(Uuid),
}

#[cfg(not(target_os = "redox"))]
fn disk_paths(_paths: &mut Vec<String>) {}

#[cfg(target_os = "redox")]
fn disk_paths(paths: &mut Vec<String>) {
use std::fs;

let mut schemes = vec![];
match fs::read_dir(":") {
Ok(entries) => for entry_res in entries {
if let Ok(entry) = entry_res {
if let Ok(path) = entry.path().into_os_string().into_string() {
let scheme = path.trim_left_matches(':');
if scheme.starts_with("disk") {
schemes.push(format!("{}:", scheme));
}
}
}
},
Err(err) => {
println!("redoxfs: failed to list schemes: {}", err);
}
}

for scheme in schemes {
match fs::read_dir(&scheme) {
Ok(entries) => for entry_res in entries {
if let Ok(entry) = entry_res {
if let Ok(path) = entry.path().into_os_string().into_string() {
paths.push(path);
}
}
},
Err(err) => {
println!("redoxfs: failed to list '{}': {}", scheme, err);
}
}
}
}

fn daemon(disk_id: &DiskId, mountpoint: &str, mut write: File) -> ! {
let mut paths = vec![];
let mut uuid_opt = None;

match *disk_id {
DiskId::Path(ref path) => {
paths.push(path.clone());
},
DiskId::Uuid(ref uuid) => {
disk_paths(&mut paths);
uuid_opt = Some(uuid.clone());
},
}

for path in paths {
println!("redoxfs: opening {}", path);
match DiskFile::open(&path).map(|image| DiskCache::new(image)) {
Ok(disk) => match redoxfs::FileSystem::open(disk) {
Ok(filesystem) => {
println!("redoxfs: opened filesystem on {} with uuid {}", path,
Uuid::from_bytes(&filesystem.header.1.uuid).unwrap().hyphenated());

let matches = if let Some(uuid) = uuid_opt {
if &filesystem.header.1.uuid == uuid.as_bytes() {
println!("redoxfs: filesystem on {} matches uuid {}", path, uuid.hyphenated());
true
} else {
println!("redoxfs: filesystem on {} does not match uuid {}", path, uuid.hyphenated());
false
}
} else {
true
};

if matches {
match mount(filesystem, &mountpoint, || {
println!("redoxfs: mounted filesystem on {} to {}", path, mountpoint);
let _ = write.write(&[0]);
}) {
Ok(()) => {
process::exit(0);
},
Err(err) => {
println!("redoxfs: failed to mount {} to {}: {}", path, mountpoint, err);
}
}
}
},
Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err)
},
Err(err) => println!("redoxfs: failed to open image {}: {}", path, err)
}
}

match *disk_id {
DiskId::Path(ref path) => {
println!("redoxfs: not able to mount path {}", path);
},
DiskId::Uuid(ref uuid) => {
println!("redoxfs: not able to mount uuid {}", uuid.hyphenated());
},
}

let _ = write.write(&[1]);
process::exit(1);
}

fn main() {
use std::io::{Read, Write};
let mut args = env::args().skip(1);

let disk_id = match args.next() {
Some(arg) => if arg == "--uuid" {
let uuid = match args.next() {
Some(arg) => match Uuid::parse_str(&arg) {
Ok(uuid) => uuid,
Err(err) => {
println!("redoxfs: invalid uuid '{}': {}", arg, err);
usage();
process::exit(1);
}
},
None => {
println!("redoxfs: no uuid provided");
usage();
process::exit(1);
}
};

DiskId::Uuid(uuid)
} else {
DiskId::Path(arg)
},
None => {
println!("redoxfs: no disk provided");
usage();
process::exit(1);
}
};

let mountpoint = match args.next() {
Some(arg) => arg,
None => {
println!("redoxfs: no mountpoint provided");
usage();
process::exit(1);
}
};

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 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 DiskFile::open(&path).map(|image| DiskCache::new(image)) {
Ok(disk) => match redoxfs::FileSystem::open(disk) {
Ok(filesystem) => {
println!("redoxfs: opened filesystem {}", path);

if let Some(mountpoint) = env::args().nth(2) {
match mount(filesystem, &mountpoint, || {
println!("redoxfs: mounted filesystem on {}:", mountpoint);
let _ = write.write(&[0]);
}) {
Ok(()) => {
process::exit(0);
},
Err(err) => {
println!("redoxfs: failed to mount {} to {}: {}", path, mountpoint, err);
}
}
} else {
println!("redoxfs: no mount point provided");
usage();
}
},
Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err)
},
Err(err) => println!("redoxfs: failed to open image {}: {}", path, err)
}

let _ = write.write(&[1]);
process::exit(1);
} else {
println!("redoxfs: no disk image provided");
usage();
}
daemon(&disk_id, &mountpoint, write);
} else if pid > 0 {
drop(write);

Expand Down

0 comments on commit e74975d

Please sign in to comment.