use crate::bad_action::BadAction;
use crate::distribution::{check_distribution};
use regex::Regex;
use std::env::current_dir;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};
use walkdir::WalkDir;
mod bad_action;
mod distribution;
mod file_attr;
mod packages;
mod release;
pub mod log_config;
pub fn check_repository(repository_dir: &Path, delete: bool) {
log::info!(repository_dir:?, delete; "start checking repository");
let bad_action = BadAction::new(delete);
let dists_dir = repository_dir.join("dists");
let pool_dir = repository_dir.join("pool");
if dists_dir.is_dir() && pool_dir.is_dir() {
if let Ok(reader) = dists_dir.read_dir() {
for entry in reader {
if let Ok(entry) = entry
&& let Ok(file_type) = entry.file_type()
&& file_type.is_dir()
&& !file_type.is_symlink()
{
check_distribution(repository_dir, &entry.path(), &bad_action);
}
}
}
} else {
check_distribution(repository_dir, repository_dir, &bad_action);
}
}
fn check_site(site_dir: &Path, delete: bool) {
log::info!(site_dir:?, delete; "start checking site");
WalkDir::new(site_dir)
.into_iter()
.filter_map(|entry| entry.ok())
.filter(|entry| entry.file_type().is_dir() && entry.file_name().to_str() == Some("dists"))
.filter_map(|entry| entry.path().parent().map(|p| p.to_path_buf()))
.for_each(|repository_dir| {
check_repository(&repository_dir, delete);
});
}
pub fn check_mirror<P>(base_dir: P, delete: bool)
where
P: AsRef<Path>,
{
let base_dir = base_dir.as_ref();
let mirror_dir = base_dir.join("mirror");
log::info!(base_dir:?, delete; "start checking mirror");
match mirror_dir.read_dir() {
Ok(reader) => {
for entry in reader {
if let Ok(entry) = entry
&& let Ok(file_type) = entry.file_type()
{
if file_type.is_dir() {
check_site(&entry.path(), delete);
}
}
}
}
Err(e) => {
log::error!(mirror_dir:?, e:err; "mirror directory error, maybe wrong base_dir specified");
}
}
}
fn find_base_dir_in_apt_mirror_config() -> Option<PathBuf> {
if let Ok(file) = File::open("/etc/apt/mirror.list") {
let re = Regex::new(r"set\s+base_path\s+([\w/-]+)").unwrap();
let reader = BufReader::new(file);
for line_result in reader.lines() {
if let Ok(line) = line_result {
if let Some(m) = re.captures(&line) {
return Some(PathBuf::from(m.get(1).unwrap().as_str()));
}
}
}
}
None
}
fn guess_base_dir(base_dir: Option<PathBuf>) -> PathBuf {
if let Some(base_dir) = base_dir {
log::info!(base_dir:?; "use user specified base_dir");
base_dir
} else if let Some(base_dir) = find_base_dir_in_apt_mirror_config() {
log::info!(base_dir:?; "use base_dir from /etc/apt/mirror.list");
base_dir
} else {
let base_dir = current_dir().unwrap(); log::info!(base_dir:?; "use current directory as base_dir");
base_dir
}
}
pub fn check_mirror_guessed(base_dir: Option<PathBuf>, delete: bool) {
check_mirror(guess_base_dir(base_dir), delete);
}