Finish from_path
for Node
This commit is contained in:
parent
2c8d05b9f8
commit
162e027365
115
src/lib.rs
115
src/lib.rs
@ -4,12 +4,13 @@ use {
|
|||||||
sha2::Sha256,
|
sha2::Sha256,
|
||||||
std::{
|
std::{
|
||||||
array::TryFromSliceError,
|
array::TryFromSliceError,
|
||||||
|
collections::HashMap,
|
||||||
fmt, fs,
|
fmt, fs,
|
||||||
io::{self, BufRead, BufReader, Read, Write},
|
io::{self, BufReader, Read, Write},
|
||||||
num::TryFromIntError,
|
num::TryFromIntError,
|
||||||
os::unix::fs::MetadataExt,
|
os::unix::fs::MetadataExt,
|
||||||
path::PathBuf,
|
|
||||||
string::FromUtf8Error,
|
string::FromUtf8Error,
|
||||||
|
sync::Mutex,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,6 +101,13 @@ impl Special {
|
|||||||
writer.write_all(&self.minor.to_le_bytes())?;
|
writer.write_all(&self.minor.to_le_bytes())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_rdev(rdev: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
major: rdev >> 8,
|
||||||
|
minor: rdev & 0xff,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -249,7 +257,7 @@ impl FileType {
|
|||||||
0 => {
|
0 => {
|
||||||
let file = File::read(reader)?;
|
let file = File::read(reader)?;
|
||||||
Ok(Self::Normal(file))
|
Ok(Self::Normal(file))
|
||||||
},
|
}
|
||||||
1 => {
|
1 => {
|
||||||
let mut len = [0; 8];
|
let mut len = [0; 8];
|
||||||
reader.read_exact(&mut len)?;
|
reader.read_exact(&mut len)?;
|
||||||
@ -289,7 +297,7 @@ impl FileType {
|
|||||||
Self::Normal(f) => {
|
Self::Normal(f) => {
|
||||||
writer.write_all(&[0])?;
|
writer.write_all(&[0])?;
|
||||||
f.write(writer)?;
|
f.write(writer)?;
|
||||||
},
|
}
|
||||||
Self::HardLink(s) => {
|
Self::HardLink(s) => {
|
||||||
writer.write_all(&[1])?;
|
writer.write_all(&[1])?;
|
||||||
let len = s.len() as u64;
|
let len = s.len() as u64;
|
||||||
@ -317,7 +325,7 @@ impl FileType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum Kind {
|
enum Kind {
|
||||||
Normal,
|
Normal,
|
||||||
Dir,
|
Dir,
|
||||||
@ -391,31 +399,92 @@ impl Node {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*pub fn from_path(path: &str) -> Result<Self, Error> {
|
pub fn from_path(
|
||||||
|
path: &str,
|
||||||
|
checksum: Checksum,
|
||||||
|
links: Mutex<HashMap<u64, String>>,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
let name = String::from(path);
|
let name = String::from(path);
|
||||||
let mut fd = fs::File::open(path)?;
|
let fd = fs::File::open(path)?;
|
||||||
let meta = fd.metadata()?;
|
let meta = fd.metadata()?;
|
||||||
let mode = meta.mode();
|
let mode = meta.mode();
|
||||||
let uid = meta.uid();
|
let uid = meta.uid();
|
||||||
let gid = meta.gid();
|
let gid = meta.gid();
|
||||||
let mtime = meta.mtime();
|
let mtime = meta.mtime().try_into()?;
|
||||||
let mut reader = BufReader::new(fd);
|
let mut reader = BufReader::new(fd);
|
||||||
let ft = meta.file_type();
|
let ft = meta.file_type();
|
||||||
let filetype = if ft.is_dir() {
|
let filetype = 'blk: {
|
||||||
FileType::Directory
|
if ft.is_dir() {
|
||||||
} else if ft.is_symlink() {
|
FileType::Directory
|
||||||
let target = fs::read_link(path)?;
|
} else if ft.is_symlink() {
|
||||||
let target = target
|
let target = fs::read_link(path)?;
|
||||||
.to_str()
|
let target = target
|
||||||
.ok_or(Error::Other("bad path".to_string()))?
|
.to_str()
|
||||||
.to_string();
|
.ok_or(Error::Other("bad path".to_string()))?
|
||||||
FileType::SoftLink(target)
|
.to_string();
|
||||||
} else if mode & 0o20000 != 0 {
|
FileType::SoftLink(target)
|
||||||
let rdev = meta.rdev();
|
} else {
|
||||||
if rdev != 0 {
|
if meta.nlink() > 1 {
|
||||||
|
if let Ok(mut list) = links.lock() {
|
||||||
|
let inode = meta.ino();
|
||||||
|
if let Some(target) = list.get(&inode).cloned() {
|
||||||
|
break 'blk FileType::HardLink(target);
|
||||||
|
} else {
|
||||||
|
list.insert(inode, name.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let kind = Kind::from(mode);
|
||||||
|
if kind == Kind::Char {
|
||||||
|
let device = Special::from_rdev(meta.rdev().try_into()?);
|
||||||
|
break 'blk FileType::Character(device);
|
||||||
|
} else if kind == Kind::Block {
|
||||||
|
let device = Special::from_rdev(meta.rdev().try_into()?);
|
||||||
|
break 'blk FileType::Block(device);
|
||||||
|
} else if kind == Kind::Pipe {
|
||||||
|
break 'blk FileType::Fifo;
|
||||||
|
} else if kind == Kind::Normal {
|
||||||
|
let mut len = meta.len();
|
||||||
|
let mut data = Vec::with_capacity(len.try_into()?);
|
||||||
|
len = reader.read_to_end(&mut data)?.try_into()?;
|
||||||
|
let checksum = match checksum {
|
||||||
|
Checksum::Md5(mut cs) => {
|
||||||
|
let mut hasher = Md5::new();
|
||||||
|
hasher.update(&data);
|
||||||
|
cs = hasher.finalize().into();
|
||||||
|
Checksum::Md5(cs)
|
||||||
|
}
|
||||||
|
Checksum::Sha1(mut cs) => {
|
||||||
|
let mut hasher = Sha1::new();
|
||||||
|
hasher.update(&data);
|
||||||
|
cs = hasher.finalize().into();
|
||||||
|
Checksum::Sha1(cs)
|
||||||
|
}
|
||||||
|
Checksum::Sha256(mut cs) => {
|
||||||
|
let mut hasher = Sha256::new();
|
||||||
|
hasher.update(&data);
|
||||||
|
cs = hasher.finalize().into();
|
||||||
|
Checksum::Sha256(cs)
|
||||||
|
}
|
||||||
|
Checksum::Skip => checksum,
|
||||||
|
};
|
||||||
|
break 'blk FileType::Normal(File {
|
||||||
|
len,
|
||||||
|
checksum,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Err(Error::UnknownFileType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
todo!()
|
|
||||||
};
|
};
|
||||||
todo!()
|
Ok(Self {
|
||||||
}*/
|
name,
|
||||||
|
mode,
|
||||||
|
uid,
|
||||||
|
gid,
|
||||||
|
mtime,
|
||||||
|
filetype,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user