diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..53d505b --- /dev/null +++ b/src/main.rs @@ -0,0 +1,74 @@ +use pathdiff::diff_paths; +use sha2::{Digest, Sha256}; +use std::fs::File; +use std::io::Read; +use std::path::{Path, PathBuf}; + +fn get_hash(fname: &str) -> Vec<u8> { + let result1 = File::open(fname); + if result1.is_err() { + return vec![]; + } + let mut result = result1.unwrap(); + let mut hasher = Sha256::new(); + loop { + let mut bif = [0; 1024]; + let ur = result.read(&mut bif); + if ur.is_err() { + return vec![]; + } + hasher.update(&bif); + if ur.unwrap() < 1024 { + break; + } + } + + hasher.finalize().to_vec() +} + +fn find_files(path: &Path) -> Vec<PathBuf> { + let mut ret = vec![]; + let fss = std::fs::read_dir(path).unwrap(); + for fs in fss { + let fs = fs.unwrap(); + if fs.file_type().unwrap().is_file() { + ret.push(fs.path()); + } else if fs.file_type().unwrap().is_dir() { + let mut p = PathBuf::from(path); + p.push(fs.file_name().to_str().unwrap()); + ret.extend(find_files(p.as_path())); + } + } + ret +} + +fn linkdup(path: &Path) { + let mut fhtable = vec![]; + for z in find_files(path) { + let pth = z; + let hsh = get_hash(pth.to_str().unwrap()); + fhtable.push((pth.to_str().unwrap().to_string(), hsh)); + } + fhtable.sort_by(|x, y| Ord::cmp(&x.0, &y.0)); + let mut fable: Vec<(String, Vec<u8>)> = vec![]; + for f in fhtable { + let prstr = fable + .iter() + .filter_map(|x| if x.1 == f.1 { Some(x.0.clone()) } else { None }) + .next(); + if prstr.is_some() { + // let f2m = std::fs::metadata(f.0.clone()).unwrap(); + std::fs::remove_file(f.0.clone()).unwrap(); + let mut zz = PathBuf::from(f.0.clone()); + zz.pop(); + std::os::unix::fs::symlink(diff_paths(prstr.unwrap(), zz).unwrap(), f.0.clone()) + .unwrap(); + } else { + fable.push(f); + } + } +} + +fn main() { + linkdup(PathBuf::from(".").as_path()); +} |
