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