diff --git a/src/bin/pxar.rs b/src/bin/pxar.rs index 095a2713..df573ae8 100644 --- a/src/bin/pxar.rs +++ b/src/bin/pxar.rs @@ -94,6 +94,9 @@ fn extract_archive( 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 no_device_nodes = param["no-device-nodes"].as_bool().unwrap_or(false); + let no_fifos = param["no-fifos"].as_bool().unwrap_or(false); + let no_sockets = param["no-sockets"].as_bool().unwrap_or(false); let allow_existing_dirs = param["allow-existing-dirs"].as_bool().unwrap_or(false); let files_from = param["files-from"].as_str(); let empty = Vec::new(); @@ -109,6 +112,15 @@ fn extract_archive( if no_acls { feature_flags ^= pxar::CA_FORMAT_WITH_ACL; } + if no_device_nodes { + feature_flags ^= pxar::CA_FORMAT_WITH_DEVICE_NODES; + } + if no_fifos { + feature_flags ^= pxar::CA_FORMAT_WITH_FIFOS; + } + if no_sockets { + feature_flags ^= pxar::CA_FORMAT_WITH_SOCKETS; + } let mut pattern_list = Vec::new(); if let Some(filename) = files_from { @@ -158,6 +170,9 @@ fn create_archive( 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 no_device_nodes = param["no-device-nodes"].as_bool().unwrap_or(false); + let no_fifos = param["no-fifos"].as_bool().unwrap_or(false); + let no_sockets = param["no-sockets"].as_bool().unwrap_or(false); let devices = if all_file_systems { None } else { Some(HashSet::new()) }; @@ -183,6 +198,15 @@ fn create_archive( if no_acls { feature_flags ^= pxar::CA_FORMAT_WITH_ACL; } + if no_device_nodes { + feature_flags ^= pxar::CA_FORMAT_WITH_DEVICE_NODES; + } + if no_fifos { + feature_flags ^= pxar::CA_FORMAT_WITH_FIFOS; + } + if no_sockets { + feature_flags ^= pxar::CA_FORMAT_WITH_SOCKETS; + } pxar::Encoder::encode(source, &mut dir, &mut writer, devices, verbose, false, feature_flags)?; @@ -205,6 +229,9 @@ fn main() { .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)) + .optional("no-device-nodes", BooleanSchema::new("Ignore device nodes.").default(false)) + .optional("no-fifos", BooleanSchema::new("Ignore fifos.").default(false)) + .optional("no-sockets", BooleanSchema::new("Ignore sockets.").default(false)) )) .arg_param(vec!["archive", "source"]) .completion_cb("archive", tools::complete_file_name) @@ -229,6 +256,9 @@ fn main() { .optional("no-acls", BooleanSchema::new("Ignore access control list entries.").default(false)) .optional("allow-existing-dirs", BooleanSchema::new("Allows directories to already exist on restore.").default(false)) .optional("files-from", StringSchema::new("Match pattern for files to restore.")) + .optional("no-device-nodes", BooleanSchema::new("Ignore device nodes.").default(false)) + .optional("no-fifos", BooleanSchema::new("Ignore fifos.").default(false)) + .optional("no-sockets", BooleanSchema::new("Ignore sockets.").default(false)) )) .arg_param(vec!["archive", "pattern"]) .completion_cb("archive", tools::complete_file_name) diff --git a/src/pxar/encoder.rs b/src/pxar/encoder.rs index b00021dd..400ab38a 100644 --- a/src/pxar/encoder.rs +++ b/src/pxar/encoder.rs @@ -809,11 +809,26 @@ impl <'a, W: Write> Encoder<'a, W> { Err(err) => bail!("readlink {:?} failed - {}", self.full_path(), err), } } else if is_block_dev(&stat) || is_char_dev(&stat) { - self.write_filename(&filename)?; - self.encode_device(&stat)?; - } else if is_fifo(&stat) || is_socket(&stat) { - self.write_filename(&filename)?; - self.encode_special(&stat)?; + if self.has_features(CA_FORMAT_WITH_DEVICE_NODES) { + self.write_filename(&filename)?; + self.encode_device(&stat)?; + } else { + eprintln!("skip device node: {:?}", self.full_path()); + } + } else if is_fifo(&stat) { + if self.has_features(CA_FORMAT_WITH_FIFOS) { + self.write_filename(&filename)?; + self.encode_special(&stat)?; + } else { + eprintln!("skip fifo: {:?}", self.full_path()); + } + } else if is_socket(&stat) { + if self.has_features(CA_FORMAT_WITH_SOCKETS) { + self.write_filename(&filename)?; + self.encode_special(&stat)?; + } else { + eprintln!("skip socket: {:?}", self.full_path()); + } } else { bail!("unsupported file type (mode {:o} {:?})", stat.st_mode, self.full_path()); } diff --git a/src/pxar/sequential_decoder.rs b/src/pxar/sequential_decoder.rs index 65288cc2..cadafd70 100644 --- a/src/pxar/sequential_decoder.rs +++ b/src/pxar/sequential_decoder.rs @@ -508,6 +508,9 @@ impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F entry: &CaFormatEntry, filename: &OsStr ) -> Result<(), Error> { + if !self.has_features(CA_FORMAT_WITH_SOCKETS) { + return Ok(()); + } if let Some(fd) = parent_fd { self.restore_socket_at(fd, filename)?; self.restore_mode_at(&entry, fd, filename)?; @@ -524,6 +527,9 @@ impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F entry: &CaFormatEntry, filename: &OsStr ) -> Result<(), Error> { + if !self.has_features(CA_FORMAT_WITH_FIFOS) { + return Ok(()); + } if let Some(fd) = parent_fd { self.restore_fifo_at(fd, filename)?; self.restore_mode_at(&entry, fd, filename)?; @@ -545,6 +551,9 @@ impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F bail!("got unknown header type inside device entry {:016x}", head.htype); } let device: CaFormatDevice = self.read_item()?; + if !self.has_features(CA_FORMAT_WITH_DEVICE_NODES) { + return Ok(()); + } if let Some(fd) = parent_fd { self.restore_device_at(&entry, fd, filename, &device)?; self.restore_mode_at(&entry, fd, filename)?;