mirror of
https://github.com/rustic-rs/rustic.git
synced 2025-10-26 11:18:51 +00:00
adapt tree json format to restic's tree format
This commit is contained in:
parent
4a3755d18a
commit
06256e7a54
@ -107,7 +107,8 @@ impl<BE: DecryptWriteBackend, I: IndexedBackend> Archiver<BE, I> {
|
||||
pub async fn finish_trees(&mut self, path: &Path) -> Result<()> {
|
||||
while !path.starts_with(&self.path) {
|
||||
// save tree and go back to parent dir
|
||||
let chunk = self.tree.serialize()?;
|
||||
let mut chunk = self.tree.serialize()?;
|
||||
chunk.push('\n' as u8); // for whatever reason, restic adds a newline, so to be compatible...
|
||||
let id = hash(&chunk);
|
||||
|
||||
let (mut node, tree, parent) = self
|
||||
|
||||
@ -182,10 +182,10 @@ fn map_entry(entry: DirEntry, with_atime: bool, cache: &UsersCache) -> Result<(P
|
||||
.into(),
|
||||
);
|
||||
let size = if m.is_dir() { 0 } else { m.len() };
|
||||
let mode = m.st_mode();
|
||||
let mode = map_mode_to_go(m.st_mode());
|
||||
let inode = m.st_ino();
|
||||
let device_id = m.st_dev();
|
||||
let links = m.st_nlink();
|
||||
let links = if m.is_dir() { 0 } else { m.st_nlink() };
|
||||
|
||||
let meta = Metadata {
|
||||
size,
|
||||
@ -211,3 +211,62 @@ fn map_entry(entry: DirEntry, with_atime: bool, cache: &UsersCache) -> Result<(P
|
||||
};
|
||||
Ok((entry.path().to_path_buf(), node))
|
||||
}
|
||||
|
||||
const MODE_PERM: u32 = 0o777; // permission bits
|
||||
|
||||
// consts from https://pkg.go.dev/io/fs#ModeType
|
||||
const GO_MODE_DIR: u32 = 0b10000000000000000000000000000000;
|
||||
const GO_MODE_SYMLINK: u32 = 0b00000100000000000000000000000000;
|
||||
const GO_MODE_DEVICE: u32 = 0b00000010000000000000000000000000;
|
||||
const GO_MODE_FIFO: u32 = 0b00000001000000000000000000000000;
|
||||
const GO_MODE_SOCKET: u32 = 0b00000000100000000000000000000000;
|
||||
const GO_MODE_SETUID: u32 = 0b00000000010000000000000000000000;
|
||||
const GO_MODE_SETGID: u32 = 0b00000000001000000000000000000000;
|
||||
const GO_MODE_CHARDEV: u32 = 0b00000000000100000000000000000000;
|
||||
const GO_MODE_STICKY: u32 = 0b00000000000010000000000000000000;
|
||||
const GO_MODE_IRREG: u32 = 0b00000000000001000000000000000000;
|
||||
|
||||
// consts from man page inode(7)
|
||||
const S_IFFORMAT: u32 = 0o170000; // File mask
|
||||
const S_IFSOCK: u32 = 0o140000; // socket
|
||||
const S_IFLNK: u32 = 0o120000; // symbolic link
|
||||
const S_IFREG: u32 = 0o100000; // regular file
|
||||
const S_IFBLK: u32 = 0o060000; // block device
|
||||
const S_IFDIR: u32 = 0o040000; // directory
|
||||
const S_IFCHR: u32 = 0o020000; // character device
|
||||
const S_IFIFO: u32 = 0o010000; // FIFO
|
||||
|
||||
const S_ISUID: u32 = 0o4000; // set-user-ID bit (see execve(2))
|
||||
const S_ISGID: u32 = 0o2000; // set-group-ID bit (see below)
|
||||
const S_ISVTX: u32 = 0o1000; // sticky bit (see below)
|
||||
|
||||
/// map st_mode from POSIX (inode(7)) to golang's definition (https://pkg.go.dev/io/fs#ModeType)
|
||||
/// Note, that it only sets the bits os.ModePerm | os.ModeType | os.ModeSetuid | os.ModeSetgid | os.ModeSticky
|
||||
/// to stay compatible with the restic implementation
|
||||
fn map_mode_to_go(mode: u32) -> u32 {
|
||||
let mut go_mode = mode & MODE_PERM;
|
||||
|
||||
match mode & S_IFFORMAT {
|
||||
S_IFSOCK => go_mode |= GO_MODE_SOCKET,
|
||||
S_IFLNK => go_mode |= GO_MODE_SYMLINK,
|
||||
S_IFBLK => go_mode |= GO_MODE_DEVICE,
|
||||
S_IFDIR => go_mode |= GO_MODE_DIR,
|
||||
S_IFCHR => go_mode |= GO_MODE_CHARDEV,
|
||||
S_IFIFO => go_mode |= GO_MODE_FIFO,
|
||||
// note that POSIX specifies regular files, whereas golang specifies irregular files
|
||||
S_IFREG => {}
|
||||
_ => go_mode |= GO_MODE_IRREG,
|
||||
};
|
||||
|
||||
if mode & S_ISUID > 0 {
|
||||
go_mode |= GO_MODE_SETUID;
|
||||
}
|
||||
if mode & S_ISGID > 0 {
|
||||
go_mode |= GO_MODE_SETGID;
|
||||
}
|
||||
if mode & S_ISVTX > 0 {
|
||||
go_mode |= GO_MODE_STICKY;
|
||||
}
|
||||
|
||||
go_mode
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ use serde_aux::prelude::*;
|
||||
|
||||
use crate::id::Id;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Constructor, Getters)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Constructor)]
|
||||
pub struct Node {
|
||||
name: String,
|
||||
#[serde(flatten)]
|
||||
@ -18,7 +18,7 @@ pub struct Node {
|
||||
#[serde(flatten)]
|
||||
meta: Metadata,
|
||||
#[serde(default, deserialize_with = "deserialize_default_from_null")]
|
||||
content: Vec<Id>,
|
||||
content: Option<Vec<Id>>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
subtree: Option<Id>,
|
||||
}
|
||||
@ -69,7 +69,7 @@ impl Node {
|
||||
Self {
|
||||
name: name.to_str().expect("no unicode").to_string(),
|
||||
node_type: NodeType::File,
|
||||
content: Vec::new(),
|
||||
content: None,
|
||||
subtree: None,
|
||||
meta,
|
||||
}
|
||||
@ -79,7 +79,7 @@ impl Node {
|
||||
Self {
|
||||
name: name.to_str().expect("no unicode").to_string(),
|
||||
node_type: NodeType::Dir,
|
||||
content: Vec::new(),
|
||||
content: None,
|
||||
subtree: None,
|
||||
meta,
|
||||
}
|
||||
@ -91,7 +91,7 @@ impl Node {
|
||||
node_type: NodeType::Symlink {
|
||||
linktarget: target.to_str().expect("no unicode").to_string(),
|
||||
},
|
||||
content: Vec::new(),
|
||||
content: None,
|
||||
subtree: None,
|
||||
meta,
|
||||
}
|
||||
@ -106,6 +106,26 @@ impl Node {
|
||||
}
|
||||
|
||||
pub fn set_content(&mut self, content: Vec<Id>) {
|
||||
self.content = content;
|
||||
self.content = Some(content);
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn node_type(&self) -> &NodeType {
|
||||
&self.node_type
|
||||
}
|
||||
|
||||
pub fn meta(&self) -> &Metadata {
|
||||
&self.meta
|
||||
}
|
||||
|
||||
pub fn content(&self) -> &Vec<Id> {
|
||||
self.content.as_ref().unwrap()
|
||||
}
|
||||
|
||||
pub fn subtree(&self) -> &Option<Id> {
|
||||
&self.subtree
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user