]>
git.proxmox.com Git - proxmox-backup.git/blob - src/bin/pxar.rs
1 extern crate proxmox_backup
;
5 use proxmox_backup
::tools
;
6 use proxmox_backup
::cli
::*;
7 use proxmox_backup
::api_schema
::*;
8 use proxmox_backup
::api_schema
::router
::*;
10 use serde_json
::{Value}
;
13 use std
::path
::{Path, PathBuf}
;
14 use std
::fs
::OpenOptions
;
15 use std
::os
::unix
::fs
::OpenOptionsExt
;
17 use proxmox_backup
::pxar
;
22 _rpcenv
: &mut dyn RpcEnvironment
,
23 ) -> Result
<Value
, Error
> {
25 let archive
= tools
::required_string_param(¶m
, "archive")?
;
26 let file
= std
::fs
::File
::open(archive
)?
;
28 let mut reader
= std
::io
::BufReader
::new(file
);
30 let mut feature_flags
= pxar
::CA_FORMAT_DEFAULT
;
31 feature_flags ^
= pxar
::CA_FORMAT_WITH_XATTRS
;
32 feature_flags ^
= pxar
::CA_FORMAT_WITH_FCAPS
;
33 let mut decoder
= pxar
::SequentialDecoder
::new(&mut reader
, feature_flags
, |_
| Ok(()));
35 let stdout
= std
::io
::stdout();
36 let mut out
= stdout
.lock();
38 let mut path
= PathBuf
::from(".");
39 decoder
.dump_entry(&mut path
, false, &mut out
)?
;
44 fn dump_archive_from_reader
<R
: std
::io
::Read
>(reader
: &mut R
, feature_flags
: u64) -> Result
<(), Error
> {
45 let mut decoder
= pxar
::SequentialDecoder
::new(reader
, feature_flags
, |_
| Ok(()));
47 let stdout
= std
::io
::stdout();
48 let mut out
= stdout
.lock();
50 let mut path
= PathBuf
::new();
51 decoder
.dump_entry(&mut path
, true, &mut out
)?
;
59 _rpcenv
: &mut dyn RpcEnvironment
,
60 ) -> Result
<Value
, Error
> {
62 let archive
= tools
::required_string_param(¶m
, "archive")?
;
63 let with_xattrs
= param
["with-xattrs"].as_bool().unwrap_or(false);
64 let with_fcaps
= param
["with-fcaps"].as_bool().unwrap_or(false);
65 let with_acls
= param
["with-acls"].as_bool().unwrap_or(false);
67 let mut feature_flags
= pxar
::CA_FORMAT_DEFAULT
;
69 feature_flags ^
= pxar
::CA_FORMAT_WITH_XATTRS
;
72 feature_flags ^
= pxar
::CA_FORMAT_WITH_FCAPS
;
75 feature_flags ^
= pxar
::CA_FORMAT_WITH_ACL
;
79 let stdin
= std
::io
::stdin();
80 let mut reader
= stdin
.lock();
81 dump_archive_from_reader(&mut reader
, feature_flags
)?
;
83 println
!("PXAR dump: {}", archive
);
84 let file
= std
::fs
::File
::open(archive
)?
;
85 let mut reader
= std
::io
::BufReader
::new(file
);
86 dump_archive_from_reader(&mut reader
, feature_flags
)?
;
95 _rpcenv
: &mut dyn RpcEnvironment
,
96 ) -> Result
<Value
, Error
> {
98 let archive
= tools
::required_string_param(¶m
, "archive")?
;
99 let target
= tools
::required_string_param(¶m
, "target")?
;
100 let verbose
= param
["verbose"].as_bool().unwrap_or(false);
101 let no_xattrs
= param
["no-xattrs"].as_bool().unwrap_or(false);
102 let no_fcaps
= param
["no-fcaps"].as_bool().unwrap_or(false);
103 let no_acls
= param
["no-acls"].as_bool().unwrap_or(false);
105 let file
= std
::fs
::File
::open(archive
)?
;
107 let mut reader
= std
::io
::BufReader
::new(file
);
108 let mut feature_flags
= pxar
::CA_FORMAT_DEFAULT
;
110 feature_flags ^
= pxar
::CA_FORMAT_WITH_XATTRS
;
113 feature_flags ^
= pxar
::CA_FORMAT_WITH_FCAPS
;
116 feature_flags ^
= pxar
::CA_FORMAT_WITH_ACL
;
119 let mut decoder
= pxar
::SequentialDecoder
::new(&mut reader
, feature_flags
, |path
| {
121 println
!("{:?}", path
);
126 decoder
.restore(Path
::new(target
))?
;
134 _rpcenv
: &mut dyn RpcEnvironment
,
135 ) -> Result
<Value
, Error
> {
137 let archive
= tools
::required_string_param(¶m
, "archive")?
;
138 let source
= tools
::required_string_param(¶m
, "source")?
;
139 let verbose
= param
["verbose"].as_bool().unwrap_or(false);
140 let all_file_systems
= param
["all-file-systems"].as_bool().unwrap_or(false);
141 let no_xattrs
= param
["no-xattrs"].as_bool().unwrap_or(false);
142 let no_fcaps
= param
["no-fcaps"].as_bool().unwrap_or(false);
143 let no_acls
= param
["no-acls"].as_bool().unwrap_or(false);
145 let source
= PathBuf
::from(source
);
147 let mut dir
= nix
::dir
::Dir
::open(
148 &source
, nix
::fcntl
::OFlag
::O_NOFOLLOW
, nix
::sys
::stat
::Mode
::empty())?
;
150 let file
= OpenOptions
::new()
156 let mut writer
= std
::io
::BufWriter
::with_capacity(1024*1024, file
);
157 let mut feature_flags
= pxar
::CA_FORMAT_DEFAULT
;
159 feature_flags ^
= pxar
::CA_FORMAT_WITH_XATTRS
;
162 feature_flags ^
= pxar
::CA_FORMAT_WITH_FCAPS
;
165 feature_flags ^
= pxar
::CA_FORMAT_WITH_ACL
;
168 pxar
::Encoder
::encode(source
, &mut dir
, &mut writer
, all_file_systems
, verbose
, feature_flags
)?
;
177 let cmd_def
= CliCommandMap
::new()
178 .insert("create", CliCommand
::new(
181 ObjectSchema
::new("Create new .pxar archive.")
182 .required("archive", StringSchema
::new("Archive name"))
183 .required("source", StringSchema
::new("Source directory."))
184 .optional("verbose", BooleanSchema
::new("Verbose output.").default(false))
185 .optional("no-xattrs", BooleanSchema
::new("Ignore extended file attributes.").default(false))
186 .optional("no-fcaps", BooleanSchema
::new("Ignore file capabilities.").default(false))
187 .optional("no-acls", BooleanSchema
::new("Ignore access control list entries.").default(false))
188 .optional("all-file-systems", BooleanSchema
::new("Include mounted sudirs.").default(false))
190 .arg_param(vec
!["archive", "source"])
191 .completion_cb("archive", tools
::complete_file_name
)
192 .completion_cb("source", tools
::complete_file_name
)
195 .insert("extract", CliCommand
::new(
198 ObjectSchema
::new("Extract an archive.")
199 .required("archive", StringSchema
::new("Archive name."))
200 .required("target", StringSchema
::new("Target directory."))
201 .optional("verbose", BooleanSchema
::new("Verbose output.").default(false))
202 .optional("no-xattrs", BooleanSchema
::new("Ignore extended file attributes.").default(false))
203 .optional("no-fcaps", BooleanSchema
::new("Ignore file capabilities.").default(false))
204 .optional("no-acls", BooleanSchema
::new("Ignore access control list entries.").default(false))
206 .arg_param(vec
!["archive", "target"])
207 .completion_cb("archive", tools
::complete_file_name
)
208 .completion_cb("target", tools
::complete_file_name
)
211 .insert("list", CliCommand
::new(
214 ObjectSchema
::new("List the contents of an archive.")
215 .required("archive", StringSchema
::new("Archive name."))
217 .arg_param(vec
!["archive"])
218 .completion_cb("archive", tools
::complete_file_name
)
221 .insert("dump", CliCommand
::new(
224 ObjectSchema
::new("Textual dump of archive contents (debug toolkit).")
225 .required("archive", StringSchema
::new("Archive name."))
226 .optional("with-xattrs", BooleanSchema
::new("Dump extended file attributes.").default(false))
227 .optional("with-fcaps", BooleanSchema
::new("Dump file capabilities.").default(false))
228 .optional("with-acls", BooleanSchema
::new("Dump access control list entries.").default(false))
230 .arg_param(vec
!["archive"])
231 .completion_cb("archive", tools
::complete_file_name
)
235 run_cli_command(cmd_def
.into());