Begin adding from_path method for Node. Need to work out detection

of whether the file is a block/char/pipe special file and if so get
major and minor numbers.
This commit is contained in:
Nathan Fisher 2023-07-03 10:43:51 -04:00
parent f93374c70a
commit 458e572bb0

View File

@ -4,9 +4,11 @@ use {
sha2::Sha256, sha2::Sha256,
std::{ std::{
array::TryFromSliceError, array::TryFromSliceError,
fmt, fmt, fs,
io::{self, Read, Write}, io::{self, BufRead, BufReader, Read, Write},
num::TryFromIntError, num::TryFromIntError,
os::unix::fs::MetadataExt,
path::PathBuf,
string::FromUtf8Error, string::FromUtf8Error,
}, },
}; };
@ -21,6 +23,7 @@ pub enum Error {
MissingData, MissingData,
UnexpectedData, UnexpectedData,
UnknownFileType, UnknownFileType,
Other(String),
} }
impl fmt::Display for Error { impl fmt::Display for Error {
@ -34,6 +37,7 @@ impl fmt::Display for Error {
Self::MissingData => write!(f, "missing data"), Self::MissingData => write!(f, "missing data"),
Self::UnexpectedData => write!(f, "unexpected data"), Self::UnexpectedData => write!(f, "unexpected data"),
Self::UnknownFileType => write!(f, "unknown file type"), Self::UnknownFileType => write!(f, "unknown file type"),
Self::Other(s) => write!(f, "{s}"),
} }
} }
} }
@ -115,17 +119,17 @@ impl Checksum {
let mut sum = [0; 16]; let mut sum = [0; 16];
reader.read_exact(&mut sum)?; reader.read_exact(&mut sum)?;
Ok(Self::Md5(sum)) Ok(Self::Md5(sum))
}, }
1 => { 1 => {
let mut sum = [0; 20]; let mut sum = [0; 20];
reader.read_exact(&mut sum)?; reader.read_exact(&mut sum)?;
Ok(Self::Sha1(sum)) Ok(Self::Sha1(sum))
}, }
2 => { 2 => {
let mut sum = [0; 32]; let mut sum = [0; 32];
reader.read_exact(&mut sum)?; reader.read_exact(&mut sum)?;
Ok(Self::Sha256(sum)) Ok(Self::Sha256(sum))
}, }
_ => Ok(Self::Skip), _ => Ok(Self::Skip),
} }
} }
@ -135,15 +139,15 @@ impl Checksum {
Self::Md5(sum) => { Self::Md5(sum) => {
writer.write_all(&[b'0'])?; writer.write_all(&[b'0'])?;
writer.write_all(&sum[..])?; writer.write_all(&sum[..])?;
}, }
Self::Sha1(sum) => { Self::Sha1(sum) => {
writer.write_all(&[b'1'])?; writer.write_all(&[b'1'])?;
writer.write_all(&sum[..])?; writer.write_all(&sum[..])?;
}, }
Self::Sha256(sum) => { Self::Sha256(sum) => {
writer.write_all(&[b'2'])?; writer.write_all(&[b'2'])?;
writer.write_all(&sum[..])?; writer.write_all(&sum[..])?;
}, }
Self::Skip => writer.write_all(&[b'3'])?, Self::Skip => writer.write_all(&[b'3'])?,
} }
Ok(()) Ok(())
@ -172,32 +176,48 @@ impl File {
hasher.update(&data); hasher.update(&data);
let res = hasher.finalize(); let res = hasher.finalize();
if res == sum.into() { if res == sum.into() {
Ok(Self { len, checksum, data }) Ok(Self {
len,
checksum,
data,
})
} else { } else {
Err(Error::InvalidChecksum) Err(Error::InvalidChecksum)
} }
}, }
Checksum::Sha1(sum) => { Checksum::Sha1(sum) => {
let mut hasher = Sha1::new(); let mut hasher = Sha1::new();
hasher.update(&data); hasher.update(&data);
let res = hasher.finalize(); let res = hasher.finalize();
if res == sum.into() { if res == sum.into() {
Ok(Self { len, checksum, data }) Ok(Self {
len,
checksum,
data,
})
} else { } else {
Err(Error::InvalidChecksum) Err(Error::InvalidChecksum)
} }
}, }
Checksum::Sha256(sum) => { Checksum::Sha256(sum) => {
let mut hasher = Sha256::new(); let mut hasher = Sha256::new();
hasher.update(&data); hasher.update(&data);
let res = hasher.finalize(); let res = hasher.finalize();
if res == sum.into() { if res == sum.into() {
Ok(Self { len, checksum, data }) Ok(Self {
len,
checksum,
data,
})
} else { } else {
Err(Error::InvalidChecksum) Err(Error::InvalidChecksum)
} }
}, }
_ => Ok(Self { len, checksum, data }), _ => Ok(Self {
len,
checksum,
data,
}),
} }
} }
@ -337,4 +357,32 @@ impl Node {
self.filetype.write(writer)?; self.filetype.write(writer)?;
Ok(()) Ok(())
} }
/*pub fn from_path(path: &str) -> Result<Self, Error> {
let name = String::from(path);
let mut fd = fs::File::open(path)?;
let meta = fd.metadata()?;
let mode = meta.mode();
let uid = meta.uid();
let gid = meta.gid();
let mtime = meta.mtime();
let mut reader = BufReader::new(fd);
let ft = meta.file_type();
let filetype = if ft.is_dir() {
FileType::Directory
} else if ft.is_symlink() {
let target = fs::read_link(path)?;
let target = target
.to_str()
.ok_or(Error::Other("bad path".to_string()))?
.to_string();
FileType::SoftLink(target)
} else if mode & 0o20000 != 0 {
let rdev = meta.rdev();
if rdev != 0 {
}
todo!()
};
todo!()
}*/
} }