Use UID and GID tables in extraction
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Fixes #18
This commit is contained in:
parent
f5afcb9205
commit
dc9885947c
@ -195,6 +195,25 @@ impl TreeNode {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn visit_mut<F: FnMut(&mut TreeNode, &str) -> anyhow::Result<()>>(
|
||||
&mut self,
|
||||
func: &mut F,
|
||||
prefix: String,
|
||||
) -> anyhow::Result<()> {
|
||||
func(self, &prefix)?;
|
||||
if let TreeNode::Directory { children, .. } = self {
|
||||
for (name, child) in children.iter_mut() {
|
||||
if prefix.is_empty() {
|
||||
// don't want a slash prefix
|
||||
child.visit_mut(func, name.clone())?;
|
||||
} else {
|
||||
child.visit_mut(func, format!("{}/{}", prefix, name))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn exists(&self, pieces: &[&str]) -> bool {
|
||||
match pieces.first() {
|
||||
None => true,
|
||||
|
@ -15,8 +15,9 @@ use nix::unistd::{Gid, Uid};
|
||||
|
||||
use crate::chunking::RecursiveUnchunker;
|
||||
use crate::commands::fully_load_pointer;
|
||||
use crate::definitions::{RecursiveChunkRef, TreeNode};
|
||||
use crate::definitions::{FilesystemOwnership, RecursiveChunkRef, TreeNode};
|
||||
use crate::pile::{Pile, RawPile};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
pub fn extract<RP: RawPile>(
|
||||
target_path: &Path,
|
||||
@ -88,7 +89,17 @@ pub fn extract_from_pointer_name<RP: RawPile>(
|
||||
num_workers: u8,
|
||||
) -> anyhow::Result<()> {
|
||||
let (pointer_data, mut root_node) = fully_load_pointer(pile, pointer_name.as_ref())?;
|
||||
// TODO CONVERT THE UID AND GIDs!!!
|
||||
|
||||
let uid_translation_table = build_uid_translation_table(&pointer_data.uid_lookup);
|
||||
let gid_translation_table = build_gid_translation_table(&pointer_data.gid_lookup);
|
||||
|
||||
// convert the UIDs and GIDs to match this system, which may be different from the usual.
|
||||
apply_uid_and_gid_translation_tables(
|
||||
&mut root_node.node,
|
||||
&uid_translation_table,
|
||||
&gid_translation_table,
|
||||
);
|
||||
|
||||
extract(
|
||||
&target_path.join(&root_node.name),
|
||||
&mut root_node.node,
|
||||
@ -98,6 +109,83 @@ pub fn extract_from_pointer_name<RP: RawPile>(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn build_uid_translation_table(
|
||||
uid_lookup: &BTreeMap<u16, Option<String>>,
|
||||
) -> HashMap<u16, u16> {
|
||||
let mut result: HashMap<u16, u16> = Default::default();
|
||||
|
||||
for (old_uid, name) in uid_lookup.iter() {
|
||||
if let Some(name) = name {
|
||||
if let Some(user) = users::get_user_by_name(name) {
|
||||
let new_uid = user.uid() as u16;
|
||||
if new_uid != *old_uid {
|
||||
result.insert(*old_uid, new_uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn build_gid_translation_table(
|
||||
gid_lookup: &BTreeMap<u16, Option<String>>,
|
||||
) -> HashMap<u16, u16> {
|
||||
let mut result: HashMap<u16, u16> = Default::default();
|
||||
|
||||
for (old_gid, name) in gid_lookup.iter() {
|
||||
if let Some(name) = name {
|
||||
if let Some(group) = users::get_group_by_name(name) {
|
||||
let new_gid = group.gid() as u16;
|
||||
if new_gid != *old_gid {
|
||||
result.insert(*old_gid, new_gid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn apply_uid_and_gid_translation_tables(
|
||||
node: &mut TreeNode,
|
||||
uid_translation: &HashMap<u16, u16>,
|
||||
gid_translation: &HashMap<u16, u16>,
|
||||
) {
|
||||
if uid_translation.is_empty() && gid_translation.is_empty() {
|
||||
// nothing to do here :).
|
||||
return;
|
||||
}
|
||||
|
||||
let apply_to = |ownership: &mut FilesystemOwnership| {
|
||||
ownership.uid = *uid_translation
|
||||
.get(&ownership.uid)
|
||||
.unwrap_or(&ownership.uid);
|
||||
ownership.gid = *gid_translation
|
||||
.get(&ownership.gid)
|
||||
.unwrap_or(&ownership.gid);
|
||||
};
|
||||
node.visit_mut(
|
||||
&mut |node, _| {
|
||||
match node {
|
||||
TreeNode::NormalFile { ownership, .. } => {
|
||||
apply_to(ownership);
|
||||
}
|
||||
TreeNode::Directory { ownership, .. } => {
|
||||
apply_to(ownership);
|
||||
}
|
||||
TreeNode::SymbolicLink { ownership, .. } => {
|
||||
apply_to(ownership);
|
||||
}
|
||||
TreeNode::Deleted => {}
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
"".to_owned(),
|
||||
)
|
||||
.expect("Can't fail since we don't fail.");
|
||||
}
|
||||
|
||||
pub fn extract_worker<RP: RawPile>(
|
||||
pile: &Pile<RP>,
|
||||
paths: Receiver<(PathBuf, RecursiveChunkRef)>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user