summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-02-19 20:19:15 +0200
committerLars Wirzenius <liw@liw.fi>2021-02-19 20:19:15 +0200
commitff17410cbee1492a5ca87869f76a2dafb7f90430 (patch)
tree0266517f6efc8027c5c58c7634de5e7176ee1a64 /src
parent248e5ab7518746c0ac43747040290e9b5d138028 (diff)
downloadobnam2-ff17410cbee1492a5ca87869f76a2dafb7f90430.tar.gz
feat: backup and restore named pipes (FIFOs)
Diffstat (limited to 'src')
-rw-r--r--src/client.rs1
-rw-r--r--src/cmd/list_files.rs1
-rw-r--r--src/cmd/restore.rs18
-rw-r--r--src/fsentry.rs6
4 files changed, 25 insertions, 1 deletions
diff --git a/src/client.rs b/src/client.rs
index 9d1e8ff..7d1613c 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -164,6 +164,7 @@ impl BackupClient {
FilesystemKind::Directory => vec![],
FilesystemKind::Symlink => vec![],
FilesystemKind::Socket => vec![],
+ FilesystemKind::Fifo => vec![],
};
info!("upload OK for {:?}", path);
Ok(ids)
diff --git a/src/cmd/list_files.rs b/src/cmd/list_files.rs
index 4982cc2..ec3e52e 100644
--- a/src/cmd/list_files.rs
+++ b/src/cmd/list_files.rs
@@ -36,6 +36,7 @@ fn format_entry(e: &FilesystemEntry, reason: Reason) -> String {
FilesystemKind::Directory => "d",
FilesystemKind::Symlink => "l",
FilesystemKind::Socket => "s",
+ FilesystemKind::Fifo => "p",
};
format!("{} {} ({})", kind, e.pathbuf().display(), reason)
}
diff --git a/src/cmd/restore.rs b/src/cmd/restore.rs
index 147a56b..b394d7d 100644
--- a/src/cmd/restore.rs
+++ b/src/cmd/restore.rs
@@ -5,7 +5,7 @@ use crate::error::ObnamError;
use crate::fsentry::{FilesystemEntry, FilesystemKind};
use crate::generation::{LocalGeneration, LocalGenerationError};
use indicatif::{ProgressBar, ProgressStyle};
-use libc::{chmod, timespec, utimensat, AT_FDCWD};
+use libc::{chmod, mkfifo, timespec, utimensat, AT_FDCWD};
use log::{debug, error, info};
use std::ffi::CString;
use std::io::prelude::*;
@@ -73,6 +73,9 @@ struct Opt {
#[derive(Debug, thiserror::Error)]
pub enum RestoreError {
+ #[error("Could not create named pipe (FIFO) {0}")]
+ NamedPipeCreationError(PathBuf),
+
#[error(transparent)]
ClientError(#[from] ClientError),
@@ -112,6 +115,7 @@ fn restore_generation(
FilesystemKind::Directory => restore_directory(&to)?,
FilesystemKind::Symlink => restore_symlink(&to, &entry)?,
FilesystemKind::Socket => restore_socket(&to, &entry)?,
+ FilesystemKind::Fifo => restore_fifo(&to, &entry)?,
}
Ok(())
}
@@ -188,6 +192,18 @@ fn restore_socket(path: &Path, entry: &FilesystemEntry) -> RestoreResult<()> {
Ok(())
}
+fn restore_fifo(path: &Path, entry: &FilesystemEntry) -> RestoreResult<()> {
+ debug!("creating fifo {:?}", path);
+ let filename = path_to_cstring(path);
+ match unsafe { mkfifo(filename.as_ptr(), 0) } {
+ -1 => {
+ return Err(RestoreError::NamedPipeCreationError(path.to_path_buf()));
+ }
+ _ => restore_metadata(path, entry)?,
+ }
+ Ok(())
+}
+
fn restore_metadata(path: &Path, entry: &FilesystemEntry) -> RestoreResult<()> {
debug!("restoring metadata for {}", entry.pathbuf().display());
diff --git a/src/fsentry.rs b/src/fsentry.rs
index 9384ec6..570877a 100644
--- a/src/fsentry.rs
+++ b/src/fsentry.rs
@@ -129,6 +129,7 @@ pub enum FilesystemKind {
Directory,
Symlink,
Socket,
+ Fifo,
}
impl FilesystemKind {
@@ -141,6 +142,8 @@ impl FilesystemKind {
FilesystemKind::Symlink
} else if file_type.is_socket() {
FilesystemKind::Socket
+ } else if file_type.is_fifo() {
+ FilesystemKind::Fifo
} else {
panic!("unknown file type {:?}", file_type);
}
@@ -152,6 +155,7 @@ impl FilesystemKind {
FilesystemKind::Directory => 1,
FilesystemKind::Symlink => 2,
FilesystemKind::Socket => 3,
+ FilesystemKind::Fifo => 4,
}
}
@@ -161,6 +165,7 @@ impl FilesystemKind {
1 => Ok(FilesystemKind::Directory),
2 => Ok(FilesystemKind::Symlink),
3 => Ok(FilesystemKind::Socket),
+ 4 => Ok(FilesystemKind::Fifo),
_ => Err(FsEntryError::UnknownFileKindCode(code).into()),
}
}
@@ -182,6 +187,7 @@ mod test {
one_file_kind_round_trip(FilesystemKind::Directory);
one_file_kind_round_trip(FilesystemKind::Symlink);
one_file_kind_round_trip(FilesystemKind::Socket);
+ one_file_kind_round_trip(FilesystemKind::Fifo);
}
fn one_file_kind_round_trip(kind: FilesystemKind) {