catar/encoder.rs: pass magic fs number to encode_dir
This commit is contained in:
		@ -63,7 +63,9 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
 | 
			
		||||
            bail!("got unexpected file type {:?} (not a directory)", me.current_path);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        me.encode_dir(dir, &stat)?;
 | 
			
		||||
        let magic = detect_fs_type(dir)?;
 | 
			
		||||
 | 
			
		||||
        me.encode_dir(dir, &stat, magic)?;
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
@ -220,7 +222,7 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn encode_dir(&mut self, dir: &mut nix::dir::Dir, dir_stat: &FileStat)  -> Result<(), Error> {
 | 
			
		||||
    fn encode_dir(&mut self, dir: &mut nix::dir::Dir, dir_stat: &FileStat, magic: i64)  -> Result<(), Error> {
 | 
			
		||||
 | 
			
		||||
        //println!("encode_dir: {:?} start {}", self.current_path, self.writer_pos);
 | 
			
		||||
 | 
			
		||||
@ -278,28 +280,43 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
 | 
			
		||||
 | 
			
		||||
            let start_pos = self.writer_pos;
 | 
			
		||||
 | 
			
		||||
            self.write_filename(&filename)?;
 | 
			
		||||
 | 
			
		||||
            let ifmt = stat.st_mode & libc::S_IFMT;
 | 
			
		||||
 | 
			
		||||
            if ifmt == libc::S_IFDIR {
 | 
			
		||||
 | 
			
		||||
                match nix::dir::Dir::openat(rawfd, filename.as_ref(), OFlag::O_DIRECTORY|OFlag::O_NOFOLLOW, Mode::empty()) {
 | 
			
		||||
                    Ok(mut dir) => self.encode_dir(&mut dir, &stat)?,
 | 
			
		||||
                    Err(nix::Error::Sys(Errno::ENOENT)) => self.report_vanished_file(&self.current_path)?,
 | 
			
		||||
                let mut dir = match nix::dir::Dir::openat(rawfd, filename.as_ref(), OFlag::O_DIRECTORY|OFlag::O_NOFOLLOW, Mode::empty()) {
 | 
			
		||||
                    Ok(dir) => dir,
 | 
			
		||||
                    Err(nix::Error::Sys(Errno::ENOENT)) => {
 | 
			
		||||
                        self.report_vanished_file(&self.current_path)?;
 | 
			
		||||
                        continue; // fixme!!
 | 
			
		||||
                    },
 | 
			
		||||
                    Err(err) => bail!("open dir {:?} failed - {}", self.current_path, err),
 | 
			
		||||
                }
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                let child_magic = if dir_stat.st_dev != stat.st_dev {
 | 
			
		||||
                    detect_fs_type(&dir)?
 | 
			
		||||
                } else {
 | 
			
		||||
                    magic
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                self.write_filename(&filename)?;
 | 
			
		||||
                self.encode_dir(&mut dir, &stat, child_magic)?;
 | 
			
		||||
 | 
			
		||||
            } else if ifmt == libc::S_IFREG {
 | 
			
		||||
                match nix::fcntl::openat(rawfd, filename.as_ref(), OFlag::O_NOFOLLOW, Mode::empty()) {
 | 
			
		||||
                    Ok(filefd) => {
 | 
			
		||||
                        let res = self.encode_file(filefd, &stat);
 | 
			
		||||
                        let _ = nix::unistd::close(filefd); // ignore close errors
 | 
			
		||||
                        res?;
 | 
			
		||||
                    }
 | 
			
		||||
                    Err(nix::Error::Sys(Errno::ENOENT)) => self.report_vanished_file(&self.current_path)?,
 | 
			
		||||
                let filefd = match nix::fcntl::openat(rawfd, filename.as_ref(), OFlag::O_NOFOLLOW, Mode::empty()) {
 | 
			
		||||
                    Ok(filefd) => filefd,
 | 
			
		||||
                    Err(nix::Error::Sys(Errno::ENOENT)) => {
 | 
			
		||||
                        self.report_vanished_file(&self.current_path)?;
 | 
			
		||||
                        continue;
 | 
			
		||||
                    },
 | 
			
		||||
                    Err(err) => bail!("open file {:?} failed - {}", self.current_path, err),
 | 
			
		||||
                }
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                self.write_filename(&filename)?;
 | 
			
		||||
                let res = self.encode_file(filefd, &stat);
 | 
			
		||||
                let _ = nix::unistd::close(filefd); // ignore close errors
 | 
			
		||||
                res?;
 | 
			
		||||
 | 
			
		||||
            } else if ifmt == libc::S_IFLNK {
 | 
			
		||||
                let mut buffer = [0u8; libc::PATH_MAX as usize];
 | 
			
		||||
 | 
			
		||||
@ -310,15 +327,21 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
 | 
			
		||||
                match Errno::result(res) {
 | 
			
		||||
                    Ok(len) => {
 | 
			
		||||
                        buffer[len as usize] = 0u8; // add Nul byte
 | 
			
		||||
                        self.write_filename(&filename)?;
 | 
			
		||||
                        self.encode_symlink(&buffer[..((len+1) as usize)], &stat)?
 | 
			
		||||
                    }
 | 
			
		||||
                    Err(nix::Error::Sys(Errno::ENOENT)) => self.report_vanished_file(&self.current_path)?,
 | 
			
		||||
                    Err(nix::Error::Sys(Errno::ENOENT)) => {
 | 
			
		||||
                        self.report_vanished_file(&self.current_path)?;
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    Err(err) => bail!("readlink {:?} failed - {}", self.current_path, err),
 | 
			
		||||
                }
 | 
			
		||||
            } else if (ifmt == libc::S_IFBLK) || (ifmt == libc::S_IFCHR) {
 | 
			
		||||
                self.write_filename(&filename)?;
 | 
			
		||||
                self.encode_device(&stat)?;
 | 
			
		||||
            } else if (ifmt == libc::S_IFIFO) || (ifmt == libc::S_IFSOCK) {
 | 
			
		||||
                // nothing do do - entry already contains all information
 | 
			
		||||
                self.write_filename(&filename)?;
 | 
			
		||||
                self.encode_special(&stat)?;
 | 
			
		||||
            } else {
 | 
			
		||||
                bail!("unsupported file type (mode {:o} {:?})", stat.st_mode, self.current_path);
 | 
			
		||||
            }
 | 
			
		||||
@ -398,7 +421,7 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
 | 
			
		||||
 | 
			
		||||
    fn encode_device(&mut self, stat: &FileStat)  -> Result<(), Error> {
 | 
			
		||||
 | 
			
		||||
        let mut entry = self.create_entry(&stat)?;
 | 
			
		||||
        let entry = self.create_entry(&stat)?;
 | 
			
		||||
 | 
			
		||||
        self.write_entry(entry)?;
 | 
			
		||||
 | 
			
		||||
@ -413,6 +436,16 @@ impl <'a, W: Write> CaTarEncoder<'a, W> {
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // FIFO or Socket
 | 
			
		||||
    fn encode_special(&mut self, stat: &FileStat)  -> Result<(), Error> {
 | 
			
		||||
 | 
			
		||||
        let entry = self.create_entry(&stat)?;
 | 
			
		||||
 | 
			
		||||
        self.write_entry(entry)?;
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn encode_symlink(&mut self, target: &[u8], stat: &FileStat)  -> Result<(), Error> {
 | 
			
		||||
 | 
			
		||||
        //println!("encode_symlink: {:?} -> {:?}", self.current_path, target);
 | 
			
		||||
@ -446,6 +479,13 @@ fn errno_is_unsupported(errno: Errno) -> bool {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn detect_fs_type<T: AsRawFd>(fd: &T) -> Result<i64, Error> {
 | 
			
		||||
    let mut fs_stat: libc::statfs = unsafe { std::mem::uninitialized() };
 | 
			
		||||
    nix::sys::statfs::fstatfs(fd, &mut fs_stat)?;
 | 
			
		||||
 | 
			
		||||
    Ok(fs_stat.f_type)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
use nix::{convert_ioctl_res, request_code_read, ioc};
 | 
			
		||||
 | 
			
		||||
// /usr/include/linux/fs.h: #define FS_IOC_GETFLAGS _IOR('f', 1, long)
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user