diff --git a/src/main.rs b/src/main.rs index 4163ae3c484c4900bb6eca2971a40599448f6c4b..63fd7d367ae437616976b7003617ce0ab9c8e7e5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,7 +30,7 @@ macro_rules! reportln { struct Inode { path: PathBuf, - metadata: Metadata + metadata: Option<Metadata> } impl std::fmt::Debug for Inode { @@ -39,6 +39,7 @@ impl std::fmt::Debug for Inode { }} enum WalkerMessage { + Start{path: PathBuf}, Inode{path: PathBuf, metadata: Metadata}, Done } @@ -155,10 +156,10 @@ fn file_type_to_flag(file_type: &std::fs::FileType) -> char { fn dispatcher(options: clap::ArgMatches, from_walker: Receiver<WalkerMessage>) { macro_rules! parse_opt { - ($n:expr, $t:ty, $d:expr) => ( + ($n:expr, $t:ty) => ( if let Some(v) = options.value_of($n) { match v.parse::<$t>() { - Ok(val) => val, + Ok(val) => Option::Some(val), Err(_) => { println!("Argument '--{} {}' cant be parsed as '{}'", $n, v, stringify!($t)); @@ -166,12 +167,12 @@ fn dispatcher(options: clap::ArgMatches, } } } else { - $d + Option::None } ) }; - let jobs = parse_opt!("jobs", usize, 1); - let lookahead = parse_opt!("lookahead", usize, jobs * 10); + let jobs = parse_opt!("jobs", usize).unwrap_or(1); + let lookahead = parse_opt!("lookahead", usize).unwrap_or(jobs * 10); let calc_md5 = options.is_present("md5"); let calc_sha512 = options.is_present("sha512"); let flags = options_to_flags(&options); @@ -180,6 +181,10 @@ fn dispatcher(options: clap::ArgMatches, let mut worklist = WorkList::new(); let (worker_to_dispatcher, from_pool) = channel::<WorkerMessage>(); let mut done = false; + print!("#fields: size:mtime:uid:gid:mode:"); + if calc_md5 { print!("md5:"); } + if calc_sha512 { print!("sha512:"); } + println!("kind:name"); loop { // reportln!("XXX {} {} {}", done, pending, worklist.used()); if done && worklist.used() == 0 { @@ -191,6 +196,17 @@ fn dispatcher(options: clap::ArgMatches, Err(_) => break }; match message { + WalkerMessage::Start{path} => { + worklist.push_back(HashEntry { + inode: Inode { + path:path.clone(), + metadata: None + }, + kind: ' ', + md5: RefCell::new(HashOption::Unused), + sha512: RefCell::new(HashOption::Unused), + }); + }, WalkerMessage::Inode{path, metadata} => { // Push to worklist use HashOption::{Pending, Unused, None}; @@ -210,7 +226,7 @@ fn dispatcher(options: clap::ArgMatches, let index = worklist.push_back(HashEntry { inode: Inode { path:path.clone(), - metadata: metadata.clone() + metadata: Some(metadata.clone()) }, kind: kind, md5: RefCell::new(md5), @@ -287,7 +303,7 @@ fn dispatcher(options: clap::ArgMatches, } } { // First entry still has pending work break; - } else{ + } else { let front = worklist.pop_front().unwrap(); { let ref md5 = *front.md5.borrow(); @@ -302,20 +318,25 @@ fn dispatcher(options: clap::ArgMatches, Option::Some(e) => { // Failed to checksum file, report and drop reportln!("Error: {:?} {}", front.inode.path, e); - continue; + continue } _ => () } }; match front.kind { + ' ' => { + // Start of new path + println!("#path: {}", front.inode.path.display()); + continue + }, 'F' | 'L' => { - let m = &front.inode.metadata; + let m = &front.inode.metadata.unwrap(); print!("{}:{}:{}:{}:{:o}:", m.size(), m.mtime(), m.uid(), m.gid(), m.mode() & 0o7777); }, _ => { - let m = &front.inode.metadata; + let m = &front.inode.metadata.unwrap(); print!("::{}:{}:{:o}:", m.uid(), m.gid(), m.mode() & 0o7777); } @@ -344,6 +365,7 @@ fn dispatcher(options: clap::ArgMatches, } } } + println!("#endTOC") } fn main() { @@ -415,9 +437,12 @@ fn main() { tx.send( WalkerMessage::Inode{ path:p.to_owned(), metadata:m.clone()}).unwrap(); }; - let mut paths : Vec<_> = matches.values_of_os("PATH").unwrap().collect(); - paths.sort(); + let paths : Vec<_> = matches.values_of_os("PATH").unwrap().collect(); +// let mut paths : Vec<_> = matches.values_of_os("PATH").unwrap().collect(); +// paths.sort(); for p in paths { + let path = std::path::Path::new(p); + let _ = tx.send(WalkerMessage::Start{path: path.to_owned()}); walk::visit(std::path::Path::new(p), &callback).unwrap(); } tx.send(WalkerMessage::Done).unwrap();