From e74975d2f9365c7dc179f4180aa3fbc8ffa8277f Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Sat, 30 Sep 2017 20:24:59 -0600 Subject: [PATCH] Add UUID matching --- src/bin/mount.rs | 195 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 157 insertions(+), 38 deletions(-) diff --git a/src/bin/mount.rs b/src/bin/mount.rs index 98db27e..8ec6910 100644 --- a/src/bin/mount.rs +++ b/src/bin/mount.rs @@ -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 { @@ -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); -- GitLab