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.

119 lines
2.5 KiB

use std::fs::{copy as fscopy, create_dir, read_dir};
use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf;
use crate::config::Config;
use crate::error::*;
use crate::util::{get_perms, set_perms};
pub fn copy(config: &Config) -> MkrootResult<()> {
if config.verbose {
println!(
"Copying skel {} to {}",
&config.skel.display(),
&config.root_dir.display()
);
}
copy_dir(&config.skel, &config.root_dir, config.verbose)
}
fn copy_dir(src: &PathBuf, dst: &PathBuf, verbose: bool) -> MkrootResult<()> {
match read_dir(&src) {
Ok(src_dir) => {
for entry in src_dir {
match entry {
Ok(entry_match) => {
let entry_path = entry_match.path();
let mut new_dst = PathBuf::from(&dst);
new_dst.push(&entry_match.file_name());
if entry_path.is_file() {
if verbose {
println!(
"Copying {} to {}",
&entry_path.display(),
&new_dst.display()
);
copy_file(&entry_path, &new_dst)?;
}
} else if entry_path.is_dir() {
if !new_dst.exists() {
if verbose {
println!("Creating directory {}", &new_dst.display());
}
mkdir(&new_dst)?;
} else if !new_dst.is_dir() {
return Err(MkrootError::from(format!(
"Error: skel {} is a directory but target {} isn't",
&entry_path.display(),
&new_dst.display()
)));
}
let entry_perms = get_perms(&entry_path)?;
let dst_perms = get_perms(&new_dst)?;
if entry_perms != dst_perms {
if verbose {
println!(
"Setting permissions {:o} on {}",
&entry_perms.mode(),
&new_dst.display()
);
}
set_perms(&new_dst, entry_perms)?;
}
copy_dir(&entry_path, &new_dst, verbose)?;
}
}
Err(e) => {
return Err(MkrootError::from(format!(
"Error getting directory entry in {}: {}",
&src.display(),
e
)))
}
}
}
}
Err(e) => {
return Err(MkrootError::from(format!(
"Error opening directory {}: {}",
&src.display(),
e
)))
}
};
Ok(())
}
fn copy_file(src: &PathBuf, dst: &PathBuf) -> MkrootResult<()> {
if let Err(e) = fscopy(src, dst) {
return Err(MkrootError::from(format!(
"Error copying file from {} to {}: {}",
src.display(),
dst.display(),
e
)));
}
Ok(())
}
fn mkdir(path: &PathBuf) -> MkrootResult<()> {
if let Err(e) = create_dir(path) {
return Err(MkrootError::from(format!(
"Error creating directory {}: {}",
path.display(),
e
)));
}
Ok(())
}