Skip to content
Snippets Groups Projects
Commit e74975d2 authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Add UUID matching

parent db229373
No related branches found
No related tags found
No related merge requests found
...@@ -8,13 +8,16 @@ extern crate libc; ...@@ -8,13 +8,16 @@ extern crate libc;
extern crate syscall; extern crate syscall;
extern crate redoxfs; extern crate redoxfs;
extern crate uuid;
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::FromRawFd; use std::os::unix::io::FromRawFd;
use std::process; use std::process;
use redoxfs::{DiskCache, DiskFile, mount}; use redoxfs::{DiskCache, DiskFile, mount};
use uuid::Uuid;
#[cfg(unix)] #[cfg(unix)]
fn fork() -> isize { fn fork() -> isize {
...@@ -37,56 +40,172 @@ fn pipe(pipes: &mut [usize; 2]) -> isize { ...@@ -37,56 +40,172 @@ fn pipe(pipes: &mut [usize; 2]) -> isize {
} }
fn usage() { 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() { 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]; let mut pipes = [0; 2];
if pipe(&mut pipes) == 0 { if pipe(&mut pipes) == 0 {
let mut read = unsafe { File::from_raw_fd(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(); let pid = fork();
if pid == 0 { if pid == 0 {
drop(read); drop(read);
if let Some(path) = env::args().nth(1) { daemon(&disk_id, &mountpoint, write);
//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();
}
} else if pid > 0 { } else if pid > 0 {
drop(write); drop(write);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment