Commit 8f1e4e6c authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Add option to generate toc for files read from stdin

parent dd0a9539
[package]
name = "hashtoc"
version = "0.1.3"
version = "0.1.4"
authors = ["Anders Blomdell <anders.blomdell@control.lth.se>"]
build = "build.rs"
links = "libhash.a,libssl"
......
......@@ -39,7 +39,7 @@ use std::cell::RefCell;
use libc::{c_int, time_t};
use std::result::Result;
use std::io::Error as IOError;
use std::io::{self, Write};
use std::io::{self, Write, BufRead};
use bytes::BytesMut;
use std::ops::Deref;
......@@ -554,7 +554,7 @@ fn dispatcher(options: clap::ArgMatches,
zprintln!();
}
fn main() {
fn main() -> std::io::Result<()> {
let matches = App::new("hashtoc")
.version("1.0")
.author("Anders Blomdell <anders.blomdell@control.lth.se>")
......@@ -608,7 +608,11 @@ fn main() {
.arg(Arg::with_name("zero-terminated")
.short("z")
.long("zero-terminated")
.help("End lines with NULL character"))
.help("Line endings are the NULL character"))
.arg(Arg::with_name("stdin")
.long("stdin")
.required(true)
.help("Read paths from stdin"))
.arg(Arg::with_name("max_age")
.short("m")
.long("max-age")
......@@ -616,7 +620,8 @@ fn main() {
.help("max age of HASH extended attribute(s)"))
.arg(Arg::with_name("PATH")
.help("path(s) to traverse")
.required(true)
.required(false)
.conflicts_with("stdin")
.multiple(true)
.index(1))
.get_matches();
......@@ -628,18 +633,47 @@ fn main() {
let worker = thread::spawn(move|| { dispatcher(args, rx); });
(worker, tx)
};
let callback = | p:&Path, m:&Metadata | {
tx.send( WalkerMessage::Inode(
Inode{path:p.to_owned(), metadata:Some(m.clone())})).unwrap();
};
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.to_owned()));
walk::visit(std::path::Path::new(p), &callback).unwrap();
match matches.values_of_os("PATH") {
Some(_) => {
let callback = | p:&Path, m:&Metadata | {
tx.send( WalkerMessage::Inode(
Inode{path:p.to_owned(),
metadata:Some(m.clone())})).unwrap();
};
let paths : Vec<_> =
matches.values_of_os("PATH").unwrap().collect();
for p in paths {
let path = std::path::Path::new(p);
let _ = tx.send(WalkerMessage::Start(path.to_owned()));
walk::visit(std::path::Path::new(p), &callback).unwrap();
}
},
None => {
let terminator =
if matches.is_present("zero-terminated") { 0 } else { 10 };
let stdin = std::io::stdin();
let mut handle = stdin.lock();
let get_metadata= walk::metadata_getter();
loop {
let mut buf = vec![];
let len = handle.read_until(terminator, &mut buf).unwrap();
if len == 0 {
break;
}
let path = Path::new(OsStr::from_bytes(&buf[..len-1]));
let metadata = get_metadata(&path);
match metadata {
Ok(metadata) =>
tx.send(WalkerMessage::Inode(Inode {
path: path.to_owned(),
metadata: Some(metadata)
})).unwrap(),
Err(e) => { println!("{} {:?}", e, path) }
};
}
}
}
tx.send(WalkerMessage::Done).unwrap();
worker.join().unwrap();
Ok(())
}
......@@ -26,6 +26,7 @@ use std::fs::{read_dir, symlink_metadata, Metadata};
use std::os::unix::fs::MetadataExt;
use libc::{AT_FDCWD, R_OK, X_OK, AT_SYMLINK_NOFOLLOW};
use libc;
use std::io::{Error, ErrorKind};
macro_rules! reportln {
() => (writeln!(io::stderr()).unwrap_or(()));
......@@ -165,5 +166,30 @@ pub fn visit(path: &Path, cb: &Fn(&Path, &Metadata)) -> io::Result<()>
Ok(())
}
pub fn metadata_getter() -> impl Fn(&Path) -> io::Result<Metadata>
{
let do_access_check = need_access_check();
move |path: &Path| {
let metadata = symlink_metadata(path);
let access = match metadata {
Ok(ref m) => {
if ! do_access_check {
true
} else {
if m.file_type().is_dir() {
check_full_path(&path, R_OK|X_OK)
} else {
check_full_path(&path, R_OK)
}
}
},
_ => false
};
if ! access {
Err(Error::new(ErrorKind::PermissionDenied,
"Access denied"))
} else {
metadata
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment