You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
2.0 KiB

#![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<T: FnOnce()>(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<PathBuf, &'static str> {
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);
}
}
}
});
}
}