#![allow(dead_code)] #![allow(unused_imports)] extern crate sha2; use std::fs::{File}; use std::fs; use std::path::{Path, PathBuf}; use std::io::prelude::*; use sha2::{Sha256}; mod hash; mod traverse; mod pool; mod rotating_list; fn funcall(w: T) { w(); } const THREADS: usize = 3; const OUTPUT_DIR: &'static str = "./output"; const INPUT_DIR: &'static str = "./target"; macro_rules! join_path { ($($path:expr),*) => { { let mut buf = std::path::PathBuf::new(); $( buf.push($path); )+ buf } } } fn output_path(path: &Path) -> Result { let mut buf = PathBuf::new(); buf.push(OUTPUT_DIR); if let Some(path) = path.to_str() { buf.push(&path[INPUT_DIR.len()+1..]); Ok(buf) } else { Err("Bad pathspec") } } fn main() { let root = traverse::DirectoryIterator::begin(INPUT_DIR).unwrap(); let mut pools = create_pools!(THREADS); if !Path::new(OUTPUT_DIR).exists() { if let Err(err) = fs::create_dir(OUTPUT_DIR) { println!("Could not create output directory: {}", err); return; } } let hardlink_dir = join_path!(OUTPUT_DIR, ".hashlink"); if !hardlink_dir.exists() { if let Err(err) = fs::create_dir(hardlink_dir.as_path()) { println!("Could not create .hashlink directory: {}", err); return; } } for dir in root { let hardlink_dir = hardlink_dir.to_path_buf(); send!(pools.get(), move || { if let Ok(mut file) = File::open(&dir) { if let Ok(hash) = hash::FileHash::create(&mut file) { let hlpath = join_path!(hardlink_dir, hash.to_string()); if let Ok(dst) = output_path(Path::new(&dir)) { println!("{} -> {}", dir, hash); if let Some(parent) = dst.parent() { if !parent.exists() { if let Err(_) = fs::create_dir(parent) { return; } } } if !hlpath.exists() { if let Err(_) = std::fs::copy(&dir, &hlpath) { return; } } fs::hard_link(hlpath, dst); } } } }); } }