pxar: extract PxarExtractOptions
same as PxarCreateOptions, but for extraction/restore rather than create. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
		
				
					committed by
					
						 Wolfgang Bumiller
						Wolfgang Bumiller
					
				
			
			
				
	
			
			
			
						parent
						
							77486a608e
						
					
				
				
					commit
					72064fd0df
				
			| @ -1354,20 +1354,24 @@ async fn restore(param: Value) -> Result<Value, Error> { | ||||
|  | ||||
|         let mut reader = BufferedDynamicReader::new(index, chunk_reader); | ||||
|  | ||||
|         let options = proxmox_backup::pxar::PxarExtractOptions { | ||||
|             match_list: &[], | ||||
|             extract_match_default: true, | ||||
|             allow_existing_dirs, | ||||
|             on_error: None, | ||||
|         }; | ||||
|  | ||||
|         if let Some(target) = target { | ||||
|             proxmox_backup::pxar::extract_archive( | ||||
|                 pxar::decoder::Decoder::from_std(reader)?, | ||||
|                 Path::new(target), | ||||
|                 &[], | ||||
|                 true, | ||||
|                 proxmox_backup::pxar::Flags::DEFAULT, | ||||
|                 allow_existing_dirs, | ||||
|                 |path| { | ||||
|                     if verbose { | ||||
|                         println!("{:?}", path); | ||||
|                     } | ||||
|                 }, | ||||
|                 None, | ||||
|                 options, | ||||
|             ) | ||||
|             .map_err(|err| format_err!("error extracting archive - {}", err))?; | ||||
|         } else { | ||||
|  | ||||
| @ -17,31 +17,26 @@ use proxmox::api::cli::*; | ||||
| use proxmox::api::api; | ||||
|  | ||||
| use proxmox_backup::tools; | ||||
| use proxmox_backup::pxar::{fuse, format_single_line_entry, ENCODER_MAX_ENTRIES, ErrorHandler, Flags}; | ||||
| use proxmox_backup::pxar::{fuse, format_single_line_entry, ENCODER_MAX_ENTRIES, Flags, PxarExtractOptions}; | ||||
|  | ||||
| fn extract_archive_from_reader<R: std::io::Read>( | ||||
|     reader: &mut R, | ||||
|     target: &str, | ||||
|     feature_flags: Flags, | ||||
|     allow_existing_dirs: bool, | ||||
|     verbose: bool, | ||||
|     match_list: &[MatchEntry], | ||||
|     extract_match_default: bool, | ||||
|     on_error: Option<ErrorHandler>, | ||||
|     options: PxarExtractOptions, | ||||
| ) -> Result<(), Error> { | ||||
|  | ||||
|     proxmox_backup::pxar::extract_archive( | ||||
|         pxar::decoder::Decoder::from_std(reader)?, | ||||
|         Path::new(target), | ||||
|         &match_list, | ||||
|         extract_match_default, | ||||
|         feature_flags, | ||||
|         allow_existing_dirs, | ||||
|         |path| { | ||||
|             if verbose { | ||||
|                 println!("{:?}", path); | ||||
|             } | ||||
|         }, | ||||
|         on_error, | ||||
|         options, | ||||
|     ) | ||||
| } | ||||
|  | ||||
| @ -190,6 +185,13 @@ fn extract_archive( | ||||
|         }) as Box<dyn FnMut(Error) -> Result<(), Error> + Send>) | ||||
|     }; | ||||
|  | ||||
|     let options = PxarExtractOptions { | ||||
|         match_list: &match_list, | ||||
|         allow_existing_dirs, | ||||
|         extract_match_default, | ||||
|         on_error, | ||||
|     }; | ||||
|  | ||||
|     if archive == "-" { | ||||
|         let stdin = std::io::stdin(); | ||||
|         let mut reader = stdin.lock(); | ||||
| @ -197,11 +199,8 @@ fn extract_archive( | ||||
|             &mut reader, | ||||
|             &target, | ||||
|             feature_flags, | ||||
|             allow_existing_dirs, | ||||
|             verbose, | ||||
|             &match_list, | ||||
|             extract_match_default, | ||||
|             on_error, | ||||
|             options, | ||||
|         )?; | ||||
|     } else { | ||||
|         if verbose { | ||||
| @ -213,11 +212,8 @@ fn extract_archive( | ||||
|             &mut reader, | ||||
|             &target, | ||||
|             feature_flags, | ||||
|             allow_existing_dirs, | ||||
|             verbose, | ||||
|             &match_list, | ||||
|             extract_match_default, | ||||
|             on_error, | ||||
|             options, | ||||
|         )?; | ||||
|     } | ||||
|  | ||||
| @ -297,6 +293,7 @@ fn extract_archive( | ||||
|     }, | ||||
| )] | ||||
| /// Create a new .pxar archive. | ||||
| #[allow(clippy::too_many_arguments)] | ||||
| fn create_archive( | ||||
|     archive: String, | ||||
|     source: String, | ||||
|  | ||||
| @ -24,17 +24,21 @@ use crate::pxar::dir_stack::PxarDirStack; | ||||
| use crate::pxar::metadata; | ||||
| use crate::pxar::Flags; | ||||
|  | ||||
| pub struct PxarExtractOptions<'a> { | ||||
|     pub match_list: &'a[MatchEntry], | ||||
|     pub extract_match_default: bool, | ||||
|     pub allow_existing_dirs: bool, | ||||
|     pub on_error: Option<ErrorHandler>, | ||||
| } | ||||
|  | ||||
| pub type ErrorHandler = Box<dyn FnMut(Error) -> Result<(), Error> + Send>; | ||||
|  | ||||
| pub fn extract_archive<T, F>( | ||||
|     mut decoder: pxar::decoder::Decoder<T>, | ||||
|     destination: &Path, | ||||
|     match_list: &[MatchEntry], | ||||
|     extract_match_default: bool, | ||||
|     feature_flags: Flags, | ||||
|     allow_existing_dirs: bool, | ||||
|     mut callback: F, | ||||
|     on_error: Option<ErrorHandler>, | ||||
|     options: PxarExtractOptions, | ||||
| ) -> Result<(), Error> | ||||
| where | ||||
|     T: pxar::decoder::SeqRead, | ||||
| @ -69,17 +73,17 @@ where | ||||
|     let mut extractor = Extractor::new( | ||||
|         dir, | ||||
|         root.metadata().clone(), | ||||
|         allow_existing_dirs, | ||||
|         options.allow_existing_dirs, | ||||
|         feature_flags, | ||||
|     ); | ||||
|  | ||||
|     if let Some(on_error) = on_error { | ||||
|     if let Some(on_error) = options.on_error { | ||||
|         extractor.on_error(on_error); | ||||
|     } | ||||
|  | ||||
|     let mut match_stack = Vec::new(); | ||||
|     let mut err_path_stack = vec![OsString::from("/")]; | ||||
|     let mut current_match = extract_match_default; | ||||
|     let mut current_match = options.extract_match_default; | ||||
|     while let Some(entry) = decoder.next() { | ||||
|         use pxar::EntryKind; | ||||
|  | ||||
| @ -99,7 +103,7 @@ where | ||||
|  | ||||
|         extractor.set_path(entry.path().as_os_str().to_owned()); | ||||
|  | ||||
|         let match_result = match_list.matches( | ||||
|         let match_result = options.match_list.matches( | ||||
|             entry.path().as_os_str().as_bytes(), | ||||
|             Some(metadata.file_type() as u32), | ||||
|         ); | ||||
|  | ||||
| @ -59,7 +59,7 @@ mod flags; | ||||
| pub use flags::Flags; | ||||
|  | ||||
| pub use create::{create_archive, PxarCreateOptions}; | ||||
| pub use extract::{extract_archive, ErrorHandler}; | ||||
| pub use extract::{extract_archive, ErrorHandler, PxarExtractOptions}; | ||||
|  | ||||
| /// The format requires to build sorted directory lookup tables in | ||||
| /// memory, so we restrict the number of allowed entries to limit | ||||
|  | ||||
		Reference in New Issue
	
	Block a user