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> {
|
pub fn mkfifo(path: &str, mode: u32) -> Result<(), Error> {
|
||||||
let ret = unsafe { libc::mkfifo(CString::new(path)?.as_ptr(), mode.try_into()?) };
|
let ret = unsafe { libc::mkfifo(CString::new(path)?.as_ptr(), mode.try_into()?) };
|
||||||
if ret == 0 {
|
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> {
|
pub fn mknod(path: &str, mode: u32, major: u32, minor: u32) -> Result<(), Error> {
|
||||||
let dev = libc::makedev(major, minor);
|
let dev = libc::makedev(major, minor);
|
||||||
let res = unsafe { libc::mknod(CString::new(path)?.as_ptr(), mode.try_into()?, dev) };
|
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::{
|
std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fs,
|
fs,
|
||||||
io::{BufReader, Read, Write},
|
io::{BufReader, BufWriter, Read, Write},
|
||||||
os::unix::fs::{symlink, DirBuilderExt, MetadataExt},
|
os::unix::fs::{symlink, DirBuilderExt, MetadataExt},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Mutex,
|
sync::Mutex,
|
||||||
@ -156,10 +156,10 @@ impl Node {
|
|||||||
}
|
}
|
||||||
let kind = Kind::from(mode);
|
let kind = Kind::from(mode);
|
||||||
if kind == Kind::Char {
|
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);
|
break 'blk FileType::Character(device);
|
||||||
} else if kind == Kind::Block {
|
} 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);
|
break 'blk FileType::Block(device);
|
||||||
} else if kind == Kind::Pipe {
|
} else if kind == Kind::Pipe {
|
||||||
break 'blk FileType::Fifo;
|
break 'blk FileType::Fifo;
|
||||||
@ -225,10 +225,38 @@ impl Node {
|
|||||||
if euid == 0 {
|
if euid == 0 {
|
||||||
nix::chown(&path, self.uid, self.gid)?;
|
nix::chown(&path, self.uid, self.gid)?;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
FileType::Block(ref b) => todo!(),
|
FileType::Block(ref b) => {
|
||||||
FileType::Character(ref c) => todo!(),
|
if euid == 0 {
|
||||||
FileType::Normal(ref n) => todo!(),
|
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) => {
|
FileType::HardLink(ref t) => {
|
||||||
let target = if let Some(prefix) = prefix {
|
let target = if let Some(prefix) = prefix {
|
||||||
format!("{prefix}/{t}")
|
format!("{prefix}/{t}")
|
||||||
@ -236,7 +264,7 @@ impl Node {
|
|||||||
t.to_string()
|
t.to_string()
|
||||||
};
|
};
|
||||||
fs::hard_link(&target, &path)?;
|
fs::hard_link(&target, &path)?;
|
||||||
},
|
}
|
||||||
FileType::SoftLink(ref t) => {
|
FileType::SoftLink(ref t) => {
|
||||||
symlink(&self.name, t)?;
|
symlink(&self.name, t)?;
|
||||||
}
|
}
|
||||||
@ -253,7 +281,7 @@ impl Node {
|
|||||||
self.mkdir(&p)?;
|
self.mkdir(&p)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !dir.exists () {
|
if !dir.exists() {
|
||||||
fs::DirBuilder::new().mode(self.mode).create(dir)?;
|
fs::DirBuilder::new().mode(self.mode).create(dir)?;
|
||||||
}
|
}
|
||||||
if nix::geteuid() == 0 {
|
if nix::geteuid() == 0 {
|
||||||
|
@ -27,10 +27,25 @@ impl Special {
|
|||||||
Ok(())
|
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 {
|
Self {
|
||||||
major: rdev >> 8,
|
major: ((rdev >> 8) & 0xff) as u32,
|
||||||
minor: rdev & 0xff,
|
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