1 use super::*; 2 use crate::preproc::rga_preproc; 3 use ::tar::EntryType::Regular; 4 use failure::*; 5 use lazy_static::lazy_static; 6 use log::*; 7 use std::path::PathBuf; 8 9 static EXTENSIONS: &[&str] = &["tar"]; 10 11 lazy_static! { 12 static ref METADATA: AdapterMeta = AdapterMeta { 13 name: "tar".to_owned(), 14 version: 1, 15 description: "Reads a tar file as a stream and recurses down into its contents".to_owned(), 16 recurses: true, 17 fast_matchers: EXTENSIONS 18 .iter() 19 .map(|s| FastMatcher::FileExtension(s.to_string())) 20 .collect(), 21 slow_matchers: None 22 }; 23 } 24 #[derive(Default)] 25 pub struct TarAdapter; 26 27 impl TarAdapter { new() -> TarAdapter28 pub fn new() -> TarAdapter { 29 TarAdapter 30 } 31 } 32 impl GetMetadata for TarAdapter { metadata(&self) -> &AdapterMeta33 fn metadata(&self) -> &AdapterMeta { 34 &METADATA 35 } 36 } 37 38 impl FileAdapter for TarAdapter { adapt(&self, ai: AdaptInfo, _detection_reason: &SlowMatcher) -> Fallible<()>39 fn adapt(&self, ai: AdaptInfo, _detection_reason: &SlowMatcher) -> Fallible<()> { 40 let AdaptInfo { 41 filepath_hint, 42 mut inp, 43 oup, 44 line_prefix, 45 archive_recursion_depth, 46 config, 47 .. 48 } = ai; 49 let mut archive = ::tar::Archive::new(&mut inp); 50 for entry in archive.entries()? { 51 let mut file = entry?; 52 if Regular == file.header().entry_type() { 53 let path = PathBuf::from(file.path()?.to_owned()); 54 debug!( 55 "{}|{}: {} bytes", 56 filepath_hint.display(), 57 path.display(), 58 file.header().size()?, 59 ); 60 let line_prefix = &format!("{}{}: ", line_prefix, path.display()); 61 let ai2: AdaptInfo = AdaptInfo { 62 filepath_hint: &path, 63 is_real_file: false, 64 archive_recursion_depth: archive_recursion_depth + 1, 65 inp: &mut file, 66 oup, 67 line_prefix, 68 config: config.clone(), 69 }; 70 rga_preproc(ai2)?; 71 } 72 } 73 Ok(()) 74 } 75 } 76