pxar: change logic and impl all command line flags for xattrs/fcaps/acls
Allows to individually set the flags for storing/dumping/restoring of xattrs/fcaps/acls in the cli of pxar. Changes logic so that each of them can be threated individually. Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
parent
60e589a111
commit
9b38443314
@ -48,13 +48,23 @@ fn dump_archive(
|
||||
) -> Result<Value, Error> {
|
||||
|
||||
let archive = tools::required_string_param(¶m, "archive")?;
|
||||
let with_xattrs = param["with-xattrs"].as_bool().unwrap_or(false);
|
||||
let with_fcaps = param["with-fcaps"].as_bool().unwrap_or(false);
|
||||
let with_acls = param["with-acls"].as_bool().unwrap_or(false);
|
||||
let file = std::fs::File::open(archive)?;
|
||||
|
||||
let mut reader = std::io::BufReader::new(file);
|
||||
|
||||
let mut feature_flags = pxar::CA_FORMAT_DEFAULT;
|
||||
if !with_xattrs {
|
||||
feature_flags ^= pxar::CA_FORMAT_WITH_XATTRS;
|
||||
}
|
||||
if !with_fcaps {
|
||||
feature_flags ^= pxar::CA_FORMAT_WITH_FCAPS;
|
||||
}
|
||||
if !with_acls {
|
||||
feature_flags ^= pxar::CA_FORMAT_WITH_ACL;
|
||||
}
|
||||
let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags);
|
||||
|
||||
let stdout = std::io::stdout();
|
||||
@ -79,6 +89,7 @@ fn extract_archive(
|
||||
let verbose = param["verbose"].as_bool().unwrap_or(false);
|
||||
let no_xattrs = param["no-xattrs"].as_bool().unwrap_or(false);
|
||||
let no_fcaps = param["no-fcaps"].as_bool().unwrap_or(false);
|
||||
let no_acls = param["no-acls"].as_bool().unwrap_or(false);
|
||||
|
||||
let file = std::fs::File::open(archive)?;
|
||||
|
||||
@ -90,6 +101,9 @@ fn extract_archive(
|
||||
if no_fcaps {
|
||||
feature_flags ^= pxar::CA_FORMAT_WITH_FCAPS;
|
||||
}
|
||||
if no_acls {
|
||||
feature_flags ^= pxar::CA_FORMAT_WITH_ACL;
|
||||
}
|
||||
|
||||
let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags);
|
||||
|
||||
@ -115,6 +129,7 @@ fn create_archive(
|
||||
let all_file_systems = param["all-file-systems"].as_bool().unwrap_or(false);
|
||||
let no_xattrs = param["no-xattrs"].as_bool().unwrap_or(false);
|
||||
let no_fcaps = param["no-fcaps"].as_bool().unwrap_or(false);
|
||||
let no_acls = param["no-acls"].as_bool().unwrap_or(false);
|
||||
|
||||
let source = PathBuf::from(source);
|
||||
|
||||
@ -135,6 +150,9 @@ fn create_archive(
|
||||
if no_fcaps {
|
||||
feature_flags ^= pxar::CA_FORMAT_WITH_FCAPS;
|
||||
}
|
||||
if no_acls {
|
||||
feature_flags ^= pxar::CA_FORMAT_WITH_ACL;
|
||||
}
|
||||
|
||||
pxar::Encoder::encode(source, &mut dir, &mut writer, all_file_systems, verbose, feature_flags)?;
|
||||
|
||||
@ -155,6 +173,7 @@ fn main() {
|
||||
.optional("verbose", BooleanSchema::new("Verbose output.").default(false))
|
||||
.optional("no-xattrs", BooleanSchema::new("Ignore extended file attributes.").default(false))
|
||||
.optional("no-fcaps", BooleanSchema::new("Ignore file capabilities.").default(false))
|
||||
.optional("no-acls", BooleanSchema::new("Ignore access control list entries.").default(false))
|
||||
.optional("all-file-systems", BooleanSchema::new("Include mounted sudirs.").default(false))
|
||||
))
|
||||
.arg_param(vec!["archive", "source"])
|
||||
@ -171,6 +190,7 @@ fn main() {
|
||||
.optional("verbose", BooleanSchema::new("Verbose output.").default(false))
|
||||
.optional("no-xattrs", BooleanSchema::new("Ignore extended file attributes.").default(false))
|
||||
.optional("no-fcaps", BooleanSchema::new("Ignore file capabilities.").default(false))
|
||||
.optional("no-acls", BooleanSchema::new("Ignore access control list entries.").default(false))
|
||||
))
|
||||
.arg_param(vec!["archive", "target"])
|
||||
.completion_cb("archive", tools::complete_file_name)
|
||||
@ -192,6 +212,9 @@ fn main() {
|
||||
dump_archive,
|
||||
ObjectSchema::new("Textual dump of archive contents (debug toolkit).")
|
||||
.required("archive", StringSchema::new("Archive name."))
|
||||
.optional("with-xattrs", BooleanSchema::new("Dump extended file attributes.").default(false))
|
||||
.optional("with-fcaps", BooleanSchema::new("Dump file capabilities.").default(false))
|
||||
.optional("with-acls", BooleanSchema::new("Dump access control list entries.").default(false))
|
||||
))
|
||||
.arg_param(vec!["archive"])
|
||||
.completion_cb("archive", tools::complete_file_name)
|
||||
|
@ -220,16 +220,22 @@ impl <'a, W: Write> Encoder<'a, W> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// True if all of the given feature flags are set in the Encoder, false otherwise
|
||||
fn has_features(&self, feature_flags: u64) -> bool {
|
||||
(self.feature_flags & feature_flags) == feature_flags
|
||||
}
|
||||
|
||||
/// True if at least one of the given feature flags is set in the Encoder, false otherwise
|
||||
fn has_some_features(&self, feature_flags: u64) -> bool {
|
||||
(self.feature_flags & feature_flags) != 0
|
||||
}
|
||||
|
||||
fn read_xattrs(&self, fd: RawFd, stat: &FileStat) -> Result<(Vec<CaFormatXAttr>, Option<CaFormatFCaps>), Error> {
|
||||
let mut xattrs = Vec::new();
|
||||
let mut fcaps = None;
|
||||
|
||||
let flags = CA_FORMAT_WITH_XATTRS | CA_FORMAT_WITH_FCAPS;
|
||||
if !self.has_features(flags) {
|
||||
if !self.has_some_features(flags) {
|
||||
return Ok((xattrs, fcaps));
|
||||
}
|
||||
// Should never be called on symlinks, just in case check anyway
|
||||
@ -260,11 +266,13 @@ impl <'a, W: Write> Encoder<'a, W> {
|
||||
};
|
||||
|
||||
if xattr::is_security_capability(&name) {
|
||||
if self.has_features(CA_FORMAT_WITH_FCAPS) {
|
||||
// fcaps are stored in own format within the archive
|
||||
fcaps = Some(CaFormatFCaps {
|
||||
data: value,
|
||||
});
|
||||
} else {
|
||||
}
|
||||
} else if self.has_features(CA_FORMAT_WITH_XATTRS) {
|
||||
xattrs.push(CaFormatXAttr {
|
||||
name: name.to_vec(),
|
||||
value: value,
|
||||
|
@ -778,20 +778,56 @@ impl <'a, R: Read> SequentialDecoder<'a, R> {
|
||||
}
|
||||
|
||||
fn dump_if_attribute(&mut self, header: &CaFormatHeader, verbose: bool) -> Result<bool, Error> {
|
||||
let dump_string = match header.htype {
|
||||
CA_FORMAT_XATTR => format!("XAttr: {:?}", self.read_xattr((header.size - HEADER_SIZE) as usize)?),
|
||||
CA_FORMAT_FCAPS => format!("FCaps: {:?}", self.read_fcaps((header.size - HEADER_SIZE) as usize)?),
|
||||
CA_FORMAT_ACL_USER => format!("ACLUser: {:?}", self.read_item::<CaFormatACLUser>()?),
|
||||
CA_FORMAT_ACL_GROUP => format!("ACLGroup: {:?}", self.read_item::<CaFormatACLGroup>()?),
|
||||
CA_FORMAT_ACL_GROUP_OBJ => format!("ACLGroupObj: {:?}", self.read_item::<CaFormatACLGroupObj>()?),
|
||||
CA_FORMAT_ACL_DEFAULT => format!("ACLDefault: {:?}", self.read_item::<CaFormatACLDefault>()?),
|
||||
CA_FORMAT_ACL_DEFAULT_USER => format!("ACLDefaultUser: {:?}", self.read_item::<CaFormatACLUser>()?),
|
||||
CA_FORMAT_ACL_DEFAULT_GROUP => format!("ACLDefaultGroup: {:?}", self.read_item::<CaFormatACLGroup>()?),
|
||||
match header.htype {
|
||||
CA_FORMAT_XATTR => {
|
||||
let xattr = self.read_xattr((header.size - HEADER_SIZE) as usize)?;
|
||||
if verbose && self.has_features(CA_FORMAT_WITH_XATTRS) {
|
||||
println!("XAttr: {:?}", xattr);
|
||||
}
|
||||
},
|
||||
CA_FORMAT_FCAPS => {
|
||||
let fcaps = self.read_fcaps((header.size - HEADER_SIZE) as usize)?;
|
||||
if verbose && self.has_features(CA_FORMAT_WITH_FCAPS) {
|
||||
println!("FCaps: {:?}", fcaps);
|
||||
}
|
||||
},
|
||||
CA_FORMAT_ACL_USER => {
|
||||
let user = self.read_item::<CaFormatACLUser>()?;
|
||||
if verbose && self.has_features(CA_FORMAT_WITH_ACL) {
|
||||
println!("ACLUser: {:?}", user);
|
||||
}
|
||||
},
|
||||
CA_FORMAT_ACL_GROUP => {
|
||||
let group = self.read_item::<CaFormatACLGroup>()?;
|
||||
if verbose && self.has_features(CA_FORMAT_WITH_ACL) {
|
||||
println!("ACLGroup: {:?}", group);
|
||||
}
|
||||
},
|
||||
CA_FORMAT_ACL_GROUP_OBJ => {
|
||||
let group_obj = self.read_item::<CaFormatACLGroupObj>()?;
|
||||
if verbose && self.has_features(CA_FORMAT_WITH_ACL) {
|
||||
println!("ACLGroupObj: {:?}", group_obj);
|
||||
}
|
||||
},
|
||||
CA_FORMAT_ACL_DEFAULT => {
|
||||
let default = self.read_item::<CaFormatACLDefault>()?;
|
||||
if verbose && self.has_features(CA_FORMAT_WITH_ACL) {
|
||||
println!("ACLDefault: {:?}", default);
|
||||
}
|
||||
},
|
||||
CA_FORMAT_ACL_DEFAULT_USER => {
|
||||
let default_user = self.read_item::<CaFormatACLUser>()?;
|
||||
if verbose && self.has_features(CA_FORMAT_WITH_ACL) {
|
||||
println!("ACLDefaultUser: {:?}", default_user);
|
||||
}
|
||||
},
|
||||
CA_FORMAT_ACL_DEFAULT_GROUP => {
|
||||
let default_group = self.read_item::<CaFormatACLGroup>()?;
|
||||
if verbose && self.has_features(CA_FORMAT_WITH_ACL) {
|
||||
println!("ACLDefaultGroup: {:?}", default_group);
|
||||
}
|
||||
},
|
||||
_ => return Ok(false),
|
||||
};
|
||||
let flags = CA_FORMAT_WITH_XATTRS | CA_FORMAT_WITH_FCAPS | CA_FORMAT_WITH_ACL;
|
||||
if verbose && self.has_features(flags) {
|
||||
println!("{}", dump_string);
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
|
Loading…
Reference in New Issue
Block a user