Finish Node::extract
method
This commit is contained in:
parent
5fd1d09e77
commit
e5cbf16064
@ -17,6 +17,37 @@ pub fn chown(path: &str, uid: u32, gid: u32) -> Result<(), Error> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn chmod(path: &str, mode: u32) -> Result<(), Error> {
|
||||
let ret = unsafe { libc::chmod(CString::new(path)?.as_ptr(), mode) };
|
||||
if ret == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Io(io::Error::last_os_error()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub fn chmod(path: &str, mode: u32) -> Result<(), Error> {
|
||||
let ret = unsafe { libc::chmod(CString::new(path)?.as_ptr(), mode.try_into()?) };
|
||||
if ret == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Io(io::Error::last_os_error()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn mkfifo(path: &str, mode: u32) -> Result<(), Error> {
|
||||
let ret = unsafe { libc::mkfifo(CString::new(path)?.as_ptr(), mode) };
|
||||
if ret == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Io(io::Error::last_os_error()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub fn mkfifo(path: &str, mode: u32) -> Result<(), Error> {
|
||||
let ret = unsafe { libc::mkfifo(CString::new(path)?.as_ptr(), mode.try_into()?) };
|
||||
if ret == 0 {
|
||||
@ -26,6 +57,18 @@ pub fn mkfifo(path: &str, mode: u32) -> Result<(), Error> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn mknod(path: &str, mode: u32, major: u32, minor: u32) -> Result<(), Error> {
|
||||
let dev = libc::makedev(major, minor);
|
||||
let res = unsafe { libc::mknod(CString::new(path)?.as_ptr(), mode, dev) };
|
||||
if res == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Io(io::Error::last_os_error()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub fn mknod(path: &str, mode: u32, major: u32, minor: u32) -> Result<(), Error> {
|
||||
let dev = libc::makedev(major, minor);
|
||||
let res = unsafe { libc::mknod(CString::new(path)?.as_ptr(), mode.try_into()?, dev) };
|
||||
|
46
src/node.rs
46
src/node.rs
@ -6,7 +6,7 @@ use {
|
||||
std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
io::{BufReader, Read, Write},
|
||||
io::{BufReader, BufWriter, Read, Write},
|
||||
os::unix::fs::{symlink, DirBuilderExt, MetadataExt},
|
||||
path::{Path, PathBuf},
|
||||
sync::Mutex,
|
||||
@ -156,10 +156,10 @@ impl Node {
|
||||
}
|
||||
let kind = Kind::from(mode);
|
||||
if kind == Kind::Char {
|
||||
let device = Special::from_rdev(meta.rdev().try_into()?);
|
||||
let device = Special::from_rdev(meta.rdev());
|
||||
break 'blk FileType::Character(device);
|
||||
} else if kind == Kind::Block {
|
||||
let device = Special::from_rdev(meta.rdev().try_into()?);
|
||||
let device = Special::from_rdev(meta.rdev());
|
||||
break 'blk FileType::Block(device);
|
||||
} else if kind == Kind::Pipe {
|
||||
break 'blk FileType::Fifo;
|
||||
@ -225,10 +225,38 @@ impl Node {
|
||||
if euid == 0 {
|
||||
nix::chown(&path, self.uid, self.gid)?;
|
||||
}
|
||||
},
|
||||
FileType::Block(ref b) => todo!(),
|
||||
FileType::Character(ref c) => todo!(),
|
||||
FileType::Normal(ref n) => todo!(),
|
||||
}
|
||||
FileType::Block(ref b) => {
|
||||
if euid == 0 {
|
||||
nix::mknod(&path, self.mode, b.major, b.minor)?;
|
||||
}
|
||||
}
|
||||
FileType::Character(ref c) => {
|
||||
if euid == 0 {
|
||||
nix::mknod(&path, self.mode, c.major, c.minor)?;
|
||||
}
|
||||
}
|
||||
FileType::Normal(ref n) => {
|
||||
let n_path = PathBuf::from(&path);
|
||||
if let Some(p) = n_path.parent() {
|
||||
if !p.exists() {
|
||||
self.mkdir(&p)?;
|
||||
}
|
||||
}
|
||||
{
|
||||
let fd = fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.write(true)
|
||||
.open(&n_path)?;
|
||||
let mut writer = BufWriter::new(fd);
|
||||
writer.write_all(&n.data)?;
|
||||
}
|
||||
if euid == 0 {
|
||||
nix::chown(&path, self.uid, self.gid)?;
|
||||
}
|
||||
nix::chmod(&path, self.mode)?;
|
||||
}
|
||||
FileType::HardLink(ref t) => {
|
||||
let target = if let Some(prefix) = prefix {
|
||||
format!("{prefix}/{t}")
|
||||
@ -236,7 +264,7 @@ impl Node {
|
||||
t.to_string()
|
||||
};
|
||||
fs::hard_link(&target, &path)?;
|
||||
},
|
||||
}
|
||||
FileType::SoftLink(ref t) => {
|
||||
symlink(&self.name, t)?;
|
||||
}
|
||||
@ -253,7 +281,7 @@ impl Node {
|
||||
self.mkdir(&p)?;
|
||||
}
|
||||
}
|
||||
if !dir.exists () {
|
||||
if !dir.exists() {
|
||||
fs::DirBuilder::new().mode(self.mode).create(dir)?;
|
||||
}
|
||||
if nix::geteuid() == 0 {
|
||||
|
@ -27,10 +27,25 @@ impl Special {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn from_rdev(rdev: u32) -> Self {
|
||||
#[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
|
||||
pub(super) fn from_rdev(rdev: u64) -> Self {
|
||||
Self {
|
||||
major: rdev >> 8,
|
||||
minor: rdev & 0xff,
|
||||
major: ((rdev >> 8) & 0xff) as u32,
|
||||
minor: (rdev & 0xffff00ff) as u32,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(super) fn from_rdev(rdev: u64) -> Self {
|
||||
let mut major = 0;
|
||||
major |= (rdev & 0x00000000000fff00) >> 8;
|
||||
major |= (rdev & 0xfffff00000000000) >> 32;
|
||||
let mut minor = 0;
|
||||
minor |= (rdev & 0x00000000000000ff) >> 0;
|
||||
minor |= (rdev & 0x00000ffffff00000) >> 12;
|
||||
Self {
|
||||
major: major as u32,
|
||||
minor: minor as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user