summaryrefslogtreecommitdiff
path: root/src/fsentry.rs
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-12-12 10:44:50 +0200
committerLars Wirzenius <liw@liw.fi>2020-12-12 11:58:12 +0200
commit146a5fe13cba442afca954733bafd854f4448928 (patch)
tree1ae24923cc950aedb77772f167045656c2f9249a /src/fsentry.rs
parent57b85f1d11c8972cd056a339c29e28ab3b91137c (diff)
downloadobnam2-146a5fe13cba442afca954733bafd854f4448928.tar.gz
feat: back up and restore symlinks
Diffstat (limited to 'src/fsentry.rs')
-rw-r--r--src/fsentry.rs25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/fsentry.rs b/src/fsentry.rs
index fd09ea2..c66e3e0 100644
--- a/src/fsentry.rs
+++ b/src/fsentry.rs
@@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
+use std::fs::read_link;
use std::fs::{FileType, Metadata};
use std::os::linux::fs::MetadataExt;
use std::path::{Path, PathBuf};
@@ -29,12 +30,16 @@ pub struct FilesystemEntry {
mtime_ns: i64,
atime: i64,
atime_ns: i64,
+
+ // The target of a symbolic link, if any.
+ symlink_target: Option<PathBuf>,
}
#[allow(clippy::len_without_is_empty)]
impl FilesystemEntry {
- pub fn from_metadata(path: &Path, meta: &Metadata) -> Self {
- Self {
+ pub fn from_metadata(path: &Path, meta: &Metadata) -> anyhow::Result<Self> {
+ let kind = FilesystemKind::from_file_type(meta.file_type());
+ Ok(Self {
path: path.to_path_buf(),
kind: FilesystemKind::from_file_type(meta.file_type()),
len: meta.len(),
@@ -43,7 +48,12 @@ impl FilesystemEntry {
mtime_ns: meta.st_mtime_nsec(),
atime: meta.st_atime(),
atime_ns: meta.st_atime_nsec(),
- }
+ symlink_target: if kind == FilesystemKind::Symlink {
+ Some(read_link(path)?)
+ } else {
+ None
+ },
+ })
}
pub fn kind(&self) -> FilesystemKind {
@@ -81,6 +91,10 @@ impl FilesystemEntry {
pub fn is_dir(&self) -> bool {
self.kind() == FilesystemKind::Directory
}
+
+ pub fn symlink_target(&self) -> Option<PathBuf> {
+ self.symlink_target.clone()
+ }
}
/// Different types of file system entries.
@@ -88,6 +102,7 @@ impl FilesystemEntry {
pub enum FilesystemKind {
Regular,
Directory,
+ Symlink,
}
impl FilesystemKind {
@@ -96,6 +111,8 @@ impl FilesystemKind {
FilesystemKind::Regular
} else if file_type.is_dir() {
FilesystemKind::Directory
+ } else if file_type.is_symlink() {
+ FilesystemKind::Symlink
} else {
panic!("unknown file type {:?}", file_type);
}
@@ -105,6 +122,7 @@ impl FilesystemKind {
match self {
FilesystemKind::Regular => 0,
FilesystemKind::Directory => 1,
+ FilesystemKind::Symlink => 2,
}
}
@@ -112,6 +130,7 @@ impl FilesystemKind {
match code {
0 => Ok(FilesystemKind::Regular),
1 => Ok(FilesystemKind::Directory),
+ 2 => Ok(FilesystemKind::Symlink),
_ => Err(Error::UnknownFileKindCode(code).into()),
}
}