catar: encode/decode sockets and fifos

This commit is contained in:
Dietmar Maurer 2019-01-11 13:26:05 +01:00
parent 20e2043a08
commit 490683ec93
2 changed files with 48 additions and 2 deletions

View File

@ -243,6 +243,28 @@ impl <'a, R: Read + Seek> CaTarDecoder<'a, R> {
Ok(()) Ok(())
} }
fn restore_socket_at(&mut self, dirfd: RawFd, filename: &OsStr) -> Result<(), Error> {
let mode = libc::S_IFSOCK | 0o0600;
let res = filename.with_nix_path(|cstr| unsafe {
libc::mknodat(dirfd, cstr.as_ptr(), mode, 0)
})?;
Errno::result(res)?;
Ok(())
}
fn restore_fifo_at(&mut self, dirfd: RawFd, filename: &OsStr) -> Result<(), Error> {
let mode = libc::S_IFIFO | 0o0600;
let res = filename.with_nix_path(|cstr| unsafe {
libc::mkfifoat(dirfd, cstr.as_ptr(), mode)
})?;
Errno::result(res)?;
Ok(())
}
pub fn restore_sequential<F: Fn(&Path) -> Result<(), Error>>( pub fn restore_sequential<F: Fn(&Path) -> Result<(), Error>>(
&mut self, &mut self,
path: &mut PathBuf, // user for error reporting path: &mut PathBuf, // user for error reporting
@ -320,6 +342,28 @@ impl <'a, R: Read + Seek> CaTarDecoder<'a, R> {
return Ok(()); return Ok(());
} }
if ifmt == libc::S_IFSOCK {
self.restore_socket_at(parent_fd, filename)?;
self.restore_mode_at(&entry, parent_fd, filename)?;
self.restore_ugid_at(&entry, parent_fd, filename)?;
self.restore_mtime_at(&entry, parent_fd, filename)?;
return Ok(());
}
if ifmt == libc::S_IFIFO {
self.restore_fifo_at(parent_fd, filename)?;
self.restore_mode_at(&entry, parent_fd, filename)?;
self.restore_ugid_at(&entry, parent_fd, filename)?;
self.restore_mtime_at(&entry, parent_fd, filename)?;
return Ok(());
}
if (ifmt == libc::S_IFBLK) || (ifmt == libc::S_IFCHR) { if (ifmt == libc::S_IFBLK) || (ifmt == libc::S_IFCHR) {
let head: CaFormatHeader = self.read_item()?; let head: CaFormatHeader = self.read_item()?;

View File

@ -317,6 +317,8 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
} }
} else if (ifmt == libc::S_IFBLK) || (ifmt == libc::S_IFCHR) { } else if (ifmt == libc::S_IFBLK) || (ifmt == libc::S_IFCHR) {
self.encode_device(&stat)?; self.encode_device(&stat)?;
} else if (ifmt == libc::S_IFIFO) || (ifmt == libc::S_IFSOCK) {
// nothing do do - entry already contains all information
} else { } else {
bail!("unsupported file type (mode {:o} {:?})", stat.st_mode, self.current_path); bail!("unsupported file type (mode {:o} {:?})", stat.st_mode, self.current_path);
} }