master
Avril 4 years ago
parent 146792b65f
commit 0c83d8777c
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -20,8 +20,8 @@ fn funcall<T: FnOnce()>(w: T)
} }
const THREADS: usize = 3; const THREADS: usize = 3;
const OUTPUT_DIR: &'static str = "./output"; //const OUTPUT_DIR: &'static str = "./output";
const INPUT_DIR: &'static str = "./target"; //const INPUT_DIR: &'static str = "./target";
macro_rules! join_path { macro_rules! join_path {
($($path:expr),*) => { ($($path:expr),*) => {
@ -35,11 +35,11 @@ macro_rules! join_path {
} }
} }
fn output_path(path: &Path) -> Result<PathBuf, &'static str> { fn output_path(input_dir: &str, output_dir: &str, path: &Path) -> Result<PathBuf, &'static str> {
let mut buf = PathBuf::new(); let mut buf = PathBuf::new();
buf.push(OUTPUT_DIR); buf.push(output_dir);
if let Some(path) = path.to_str() { if let Some(path) = path.to_str() {
buf.push(&path[INPUT_DIR.len()+1..]); buf.push(&path[input_dir.len()+1..]);
Ok(buf) Ok(buf)
} else { } else {
Err("Bad pathspec") Err("Bad pathspec")
@ -47,18 +47,30 @@ fn output_path(path: &Path) -> Result<PathBuf, &'static str> {
} }
fn main() { fn main() {
let root = traverse::DirectoryIterator::begin(INPUT_DIR).unwrap();
let args: Vec<String> = std::env::args().collect();
if args.len() < 3 {
println!("hashlink - generate recursive file hashtable to coerce duplicate files to hardlinks.\n");
println!("Usage: {} <input> <output>", args[0]);
return;
}
let input_dir = &args[1];
let output_dir = &args[2];
let root = traverse::DirectoryIterator::begin(input_dir).unwrap();
let mut pools = create_pools!(THREADS); let mut pools = create_pools!(THREADS);
if !Path::new(OUTPUT_DIR).exists() { if !Path::new(output_dir).exists() {
if let Err(err) = fs::create_dir(OUTPUT_DIR) { if let Err(err) = fs::create_dir(output_dir) {
println!("Could not create output directory: {}", err); println!("Could not create output directory: {}", err);
return; return;
} }
} }
let hardlink_dir = join_path!(OUTPUT_DIR, ".hashlink"); let hardlink_dir = join_path!(output_dir, ".hashlink");
if !hardlink_dir.exists() { if !hardlink_dir.exists() {
if let Err(err) = fs::create_dir(hardlink_dir.as_path()) { if let Err(err) = fs::create_dir(hardlink_dir.as_path()) {
@ -69,14 +81,16 @@ fn main() {
for dir in root { for dir in root {
let hardlink_dir = hardlink_dir.to_path_buf(); let hardlink_dir = hardlink_dir.to_path_buf();
let input_dir = input_dir.to_string();
let output_dir = output_dir.to_string();
send!(pools.get(), move || { send!(pools.get(), move || {
if let Ok(mut file) = File::open(&dir) { if let Ok(mut file) = File::open(&dir) {
if let Ok(hash) = hash::FileHash::create(&mut file) { if let Ok(hash) = hash::FileHash::create(&mut file) {
let hlpath = join_path!(hardlink_dir, hash.to_string()); let hlpath = join_path!(hardlink_dir, hash.to_string());
if let Ok(dst) = output_path(Path::new(&dir)) { if let Ok(dst) = output_path(&input_dir, &output_dir, Path::new(&dir)) {
println!("{} -> {}", dir, hash);
if let Some(parent) = dst.parent() { if let Some(parent) = dst.parent() {
if !parent.exists() { if !parent.exists() {
@ -92,7 +106,10 @@ fn main() {
} }
} }
fs::hard_link(hlpath, dst); match fs::hard_link(hlpath, dst) {
Ok(_) => println!("{} -> {}", dir, hash),
Err(err) => println!("E: {} failed: {}", dir, err),
}
} }
} }
} }

Loading…
Cancel
Save