/catar/encoder.rs: do not store data from virtual file systems

This commit is contained in:
Dietmar Maurer 2019-01-12 10:20:08 +01:00
parent 80881f60ef
commit 13d98013b2

View File

@ -54,7 +54,8 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
// todo: use scandirat??
let stat = match nix::sys::stat::fstat(dir.as_raw_fd()) {
let dir_fd = dir.as_raw_fd();
let stat = match nix::sys::stat::fstat(dir_fd) {
Ok(stat) => stat,
Err(err) => bail!("fstat {:?} failed - {}", me.current_path, err),
};
@ -63,7 +64,7 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
bail!("got unexpected file type {:?} (not a directory)", me.current_path);
}
let magic = detect_fs_type(dir)?;
let magic = detect_fs_type(dir_fd)?;
me.encode_dir(dir, &stat, magic)?;
@ -241,25 +242,27 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
let mut dir_count = 0;
for entry in dir.iter() {
dir_count += 1;
if dir_count > MAX_DIRECTORY_ENTRIES {
bail!("too many directory items in {:?} (> {})",
self.current_path, MAX_DIRECTORY_ENTRIES);
if !is_virtual_file_system(magic) {
for entry in dir.iter() {
dir_count += 1;
if dir_count > MAX_DIRECTORY_ENTRIES {
bail!("too many directory items in {:?} (> {})",
self.current_path, MAX_DIRECTORY_ENTRIES);
}
let entry = match entry {
Ok(entry) => entry,
Err(err) => bail!("readir {:?} failed - {}", self.current_path, err),
};
let filename = entry.file_name().to_owned();
let name = filename.to_bytes_with_nul();
let name_len = name.len();
if name_len == 2 && name[0] == b'.' && name[1] == 0u8 { continue; }
if name_len == 3 && name[0] == b'.' && name[1] == b'.' && name[2] == 0u8 { continue; }
name_list.push(filename);
}
let entry = match entry {
Ok(entry) => entry,
Err(err) => bail!("readir {:?} failed - {}", self.current_path, err),
};
let filename = entry.file_name().to_owned();
let name = filename.to_bytes_with_nul();
let name_len = name.len();
if name_len == 2 && name[0] == b'.' && name[1] == 0u8 { continue; }
if name_len == 3 && name[0] == b'.' && name[1] == b'.' && name[2] == 0u8 { continue; }
name_list.push(filename);
}
name_list.sort_unstable_by(|a, b| a.cmp(&b));
@ -294,7 +297,7 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
};
let child_magic = if dir_stat.st_dev != stat.st_dev {
detect_fs_type(&dir)?
detect_fs_type(dir.as_raw_fd())?
} else {
magic
};
@ -312,8 +315,14 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
Err(err) => bail!("open file {:?} failed - {}", self.current_path, err),
};
let child_magic = if dir_stat.st_dev != stat.st_dev {
detect_fs_type(filefd)?
} else {
magic
};
self.write_filename(&filename)?;
let res = self.encode_file(filefd, &stat);
let res = self.encode_file(filefd, &stat, child_magic);
let _ = nix::unistd::close(filefd); // ignore close errors
res?;
@ -373,7 +382,7 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
Ok(())
}
fn encode_file(&mut self, filefd: RawFd, stat: &FileStat) -> Result<(), Error> {
fn encode_file(&mut self, filefd: RawFd, stat: &FileStat, magic: i64) -> Result<(), Error> {
//println!("encode_file: {:?}", self.current_path);
@ -384,6 +393,11 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
self.write_entry(entry)?;
if is_virtual_file_system(magic) {
self.write_header(CA_FORMAT_PAYLOAD, 0)?;
return Ok(());
}
let size = stat.st_size as u64;
self.write_header(CA_FORMAT_PAYLOAD, size)?;
@ -479,9 +493,10 @@ fn errno_is_unsupported(errno: Errno) -> bool {
}
}
fn detect_fs_type<T: AsRawFd>(fd: &T) -> Result<i64, Error> {
fn detect_fs_type(fd: RawFd) -> Result<i64, Error> {
let mut fs_stat: libc::statfs = unsafe { std::mem::uninitialized() };
nix::sys::statfs::fstatfs(fd, &mut fs_stat)?;
let res = unsafe { libc::fstatfs(fd, &mut fs_stat) };
Errno::result(res)?;
Ok(fs_stat.f_type)
}