]>
Commit | Line | Data |
---|---|---|
c60d34bd DM |
1 | extern crate proxmox_backup; |
2 | ||
3 | use failure::*; | |
4 | ||
ce7ba139 | 5 | use proxmox_backup::tools; |
4de0e142 | 6 | use proxmox_backup::cli::*; |
ef2f2efb | 7 | use proxmox_backup::api_schema::*; |
dc9a007b | 8 | use proxmox_backup::api_schema::router::*; |
c60d34bd DM |
9 | |
10 | use serde_json::{Value}; | |
11 | ||
37940aa1 | 12 | use std::io::Write; |
1ef46b81 | 13 | use std::path::{Path, PathBuf}; |
c60d34bd | 14 | |
3dbfe5b1 | 15 | use proxmox_backup::pxar; |
e86c4924 | 16 | |
6049b71f | 17 | fn print_filenames( |
37940aa1 | 18 | param: Value, |
6049b71f DM |
19 | _info: &ApiMethod, |
20 | _rpcenv: &mut RpcEnvironment, | |
21 | ) -> Result<Value, Error> { | |
e86c4924 | 22 | |
6049b71f | 23 | let archive = tools::required_string_param(¶m, "archive")?; |
e86c4924 DM |
24 | let file = std::fs::File::open(archive)?; |
25 | ||
26 | let mut reader = std::io::BufReader::new(file); | |
27 | ||
b344461b CE |
28 | let mut feature_flags = pxar::CA_FORMAT_DEFAULT; |
29 | feature_flags ^= pxar::CA_FORMAT_WITH_XATTRS; | |
30 | feature_flags ^= pxar::CA_FORMAT_WITH_FCAPS; | |
31 | let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags); | |
e86c4924 DM |
32 | |
33 | let stdout = std::io::stdout(); | |
34 | let mut out = stdout.lock(); | |
35 | ||
37940aa1 DM |
36 | let mut path = PathBuf::from("."); |
37 | decoder.dump_entry(&mut path, false, &mut out)?; | |
e86c4924 DM |
38 | |
39 | Ok(Value::Null) | |
40 | } | |
41 | ||
6049b71f DM |
42 | fn dump_archive( |
43 | param: Value, | |
44 | _info: &ApiMethod, | |
45 | _rpcenv: &mut RpcEnvironment, | |
46 | ) -> Result<Value, Error> { | |
c60d34bd | 47 | |
6049b71f | 48 | let archive = tools::required_string_param(¶m, "archive")?; |
40360fde | 49 | let file = std::fs::File::open(archive)?; |
c60d34bd | 50 | |
40360fde | 51 | let mut reader = std::io::BufReader::new(file); |
c60d34bd | 52 | |
b344461b CE |
53 | let mut feature_flags = pxar::CA_FORMAT_DEFAULT; |
54 | feature_flags ^= pxar::CA_FORMAT_WITH_XATTRS; | |
55 | feature_flags ^= pxar::CA_FORMAT_WITH_FCAPS; | |
56 | let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags); | |
c60d34bd | 57 | |
40360fde DM |
58 | let stdout = std::io::stdout(); |
59 | let mut out = stdout.lock(); | |
c60d34bd | 60 | |
40360fde | 61 | println!("PXAR dump: {}", archive); |
c60d34bd | 62 | |
37940aa1 DM |
63 | let mut path = PathBuf::new(); |
64 | decoder.dump_entry(&mut path, true, &mut out)?; | |
c60d34bd DM |
65 | |
66 | Ok(Value::Null) | |
67 | } | |
68 | ||
1ef46b81 DM |
69 | fn extract_archive( |
70 | param: Value, | |
71 | _info: &ApiMethod, | |
72 | _rpcenv: &mut RpcEnvironment, | |
73 | ) -> Result<Value, Error> { | |
74 | ||
75 | let archive = tools::required_string_param(¶m, "archive")?; | |
76 | let target = tools::required_string_param(¶m, "target")?; | |
77 | let verbose = param["verbose"].as_bool().unwrap_or(false); | |
0d9bab05 CE |
78 | let no_xattrs = param["no-xattrs"].as_bool().unwrap_or(false); |
79 | let no_fcaps = param["no-fcaps"].as_bool().unwrap_or(false); | |
1ef46b81 DM |
80 | |
81 | let file = std::fs::File::open(archive)?; | |
82 | ||
83 | let mut reader = std::io::BufReader::new(file); | |
b344461b CE |
84 | let mut feature_flags = pxar::CA_FORMAT_DEFAULT; |
85 | if no_xattrs { | |
86 | feature_flags ^= pxar::CA_FORMAT_WITH_XATTRS; | |
87 | } | |
88 | if no_fcaps { | |
89 | feature_flags ^= pxar::CA_FORMAT_WITH_FCAPS; | |
90 | } | |
1ef46b81 | 91 | |
b344461b | 92 | let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags); |
1ef46b81 DM |
93 | |
94 | decoder.restore(Path::new(target), & |path| { | |
95 | if verbose { | |
96 | println!("{:?}", path); | |
97 | } | |
98 | Ok(()) | |
99 | })?; | |
100 | ||
101 | Ok(Value::Null) | |
102 | } | |
103 | ||
6049b71f DM |
104 | fn create_archive( |
105 | param: Value, | |
106 | _info: &ApiMethod, | |
107 | _rpcenv: &mut RpcEnvironment, | |
108 | ) -> Result<Value, Error> { | |
c60d34bd | 109 | |
6049b71f DM |
110 | let archive = tools::required_string_param(¶m, "archive")?; |
111 | let source = tools::required_string_param(¶m, "source")?; | |
2689810c | 112 | let verbose = param["verbose"].as_bool().unwrap_or(false); |
e3c30c50 | 113 | let all_file_systems = param["all-file-systems"].as_bool().unwrap_or(false); |
0d9bab05 CE |
114 | let no_xattrs = param["no-xattrs"].as_bool().unwrap_or(false); |
115 | let no_fcaps = param["no-fcaps"].as_bool().unwrap_or(false); | |
02c7d8e5 | 116 | |
1ef46b81 | 117 | let source = PathBuf::from(source); |
02c7d8e5 DM |
118 | |
119 | let mut dir = nix::dir::Dir::open( | |
120 | &source, nix::fcntl::OFlag::O_NOFOLLOW, nix::sys::stat::Mode::empty())?; | |
121 | ||
122 | let file = std::fs::OpenOptions::new() | |
123 | .create_new(true) | |
124 | .write(true) | |
125 | .open(archive)?; | |
126 | ||
127 | let mut writer = std::io::BufWriter::with_capacity(1024*1024, file); | |
b344461b CE |
128 | let mut feature_flags = pxar::CA_FORMAT_DEFAULT; |
129 | if no_xattrs { | |
130 | feature_flags ^= pxar::CA_FORMAT_WITH_XATTRS; | |
131 | } | |
132 | if no_fcaps { | |
133 | feature_flags ^= pxar::CA_FORMAT_WITH_FCAPS; | |
134 | } | |
135 | ||
136 | pxar::Encoder::encode(source, &mut dir, &mut writer, all_file_systems, verbose, feature_flags)?; | |
c60d34bd | 137 | |
02c7d8e5 | 138 | writer.flush()?; |
c60d34bd DM |
139 | |
140 | Ok(Value::Null) | |
141 | } | |
142 | ||
143 | fn main() { | |
144 | ||
145 | let cmd_def = CliCommandMap::new() | |
146 | .insert("create", CliCommand::new( | |
147 | ApiMethod::new( | |
02c7d8e5 | 148 | create_archive, |
8968258b | 149 | ObjectSchema::new("Create new .pxar archive.") |
c60d34bd DM |
150 | .required("archive", StringSchema::new("Archive name")) |
151 | .required("source", StringSchema::new("Source directory.")) | |
2689810c | 152 | .optional("verbose", BooleanSchema::new("Verbose output.").default(false)) |
0d9bab05 CE |
153 | .optional("no-xattrs", BooleanSchema::new("Ignore extended file attributes.").default(false)) |
154 | .optional("no-fcaps", BooleanSchema::new("Ignore file capabilities.").default(false)) | |
e3c30c50 DM |
155 | .optional("all-file-systems", BooleanSchema::new("Include mounted sudirs.").default(false)) |
156 | )) | |
c60d34bd | 157 | .arg_param(vec!["archive", "source"]) |
ce7ba139 DM |
158 | .completion_cb("archive", tools::complete_file_name) |
159 | .completion_cb("source", tools::complete_file_name) | |
160 | .into() | |
c60d34bd | 161 | ) |
1ef46b81 DM |
162 | .insert("extract", CliCommand::new( |
163 | ApiMethod::new( | |
164 | extract_archive, | |
165 | ObjectSchema::new("Extract an archive.") | |
166 | .required("archive", StringSchema::new("Archive name.")) | |
167 | .required("target", StringSchema::new("Target directory.")) | |
168 | .optional("verbose", BooleanSchema::new("Verbose output.").default(false)) | |
0d9bab05 CE |
169 | .optional("no-xattrs", BooleanSchema::new("Ignore extended file attributes.").default(false)) |
170 | .optional("no-fcaps", BooleanSchema::new("Ignore file capabilities.").default(false)) | |
1ef46b81 DM |
171 | )) |
172 | .arg_param(vec!["archive", "target"]) | |
173 | .completion_cb("archive", tools::complete_file_name) | |
174 | .completion_cb("target", tools::complete_file_name) | |
175 | .into() | |
176 | ) | |
e86c4924 DM |
177 | .insert("list", CliCommand::new( |
178 | ApiMethod::new( | |
179 | print_filenames, | |
180 | ObjectSchema::new("List the contents of an archive.") | |
181 | .required("archive", StringSchema::new("Archive name.")) | |
182 | )) | |
183 | .arg_param(vec!["archive"]) | |
ce7ba139 | 184 | .completion_cb("archive", tools::complete_file_name) |
e86c4924 DM |
185 | .into() |
186 | ) | |
c60d34bd DM |
187 | .insert("dump", CliCommand::new( |
188 | ApiMethod::new( | |
189 | dump_archive, | |
190 | ObjectSchema::new("Textual dump of archive contents (debug toolkit).") | |
191 | .required("archive", StringSchema::new("Archive name.")) | |
192 | )) | |
193 | .arg_param(vec!["archive"]) | |
ce7ba139 | 194 | .completion_cb("archive", tools::complete_file_name) |
c60d34bd DM |
195 | .into() |
196 | ); | |
197 | ||
698d9d44 | 198 | run_cli_command(cmd_def.into()); |
c60d34bd | 199 | } |