@@ -6,19 +6,40 @@ use selinux_cascade::error::ErrorItem;
6
6
use clap:: Parser ;
7
7
use std:: fs:: File ;
8
8
use std:: io:: { Error , ErrorKind , Write } ;
9
+ use walkdir:: WalkDir ;
9
10
10
11
#[ derive( Parser , Debug ) ]
11
- #[ clap( author, version, name = "casc" ) ]
12
+ #[ clap( author, version, name = "casc" , about ) ]
12
13
struct Args {
14
+ /// List of input files to process. Directories are searched recursively.
13
15
#[ clap( required( true ) ) ]
14
16
input_file : Vec < String > ,
15
17
}
16
18
17
19
fn main ( ) -> std:: io:: Result < ( ) > {
18
20
let args = Args :: parse ( ) ;
19
- let policies: Vec < & str > = args. input_file . iter ( ) . map ( |s| s as & str ) . collect ( ) ;
21
+ let policies: Vec < String > = match get_policy_files ( args. input_file ) {
22
+ Ok ( mut s) => {
23
+ // Always treat files in the same order for determinism in compilation
24
+ // sort_unstable() does not preserve equality, which is fine because two
25
+ // different files cannot have the same relative path
26
+ s. sort_unstable ( ) ;
27
+ s
28
+ }
29
+ Err ( e) => {
30
+ eprintln ! ( "{}" , e) ;
31
+ return Err ( e) ;
32
+ }
33
+ } ;
34
+ if policies. is_empty ( ) {
35
+ // Files supplied on command line, but no .cas files found
36
+ return Err ( Error :: new (
37
+ ErrorKind :: InvalidData ,
38
+ "No policy source files found" ,
39
+ ) ) ;
40
+ }
20
41
let mut out_file = File :: create ( "out.cil" ) ?;
21
- let res = compile_system_policy ( policies) ;
42
+ let res = compile_system_policy ( policies. iter ( ) . map ( |s| s as & str ) . collect ( ) ) ;
22
43
match res {
23
44
Err ( error_list) => {
24
45
for e in error_list {
@@ -35,3 +56,19 @@ fn main() -> std::io::Result<()> {
35
56
Ok ( s) => out_file. write_all ( s. as_bytes ( ) ) ,
36
57
}
37
58
}
59
+
60
+ // Create a list of policy files
61
+ fn get_policy_files ( filenames : Vec < String > ) -> Result < Vec < String > , Error > {
62
+ let mut policy_files = Vec :: new ( ) ;
63
+ for file in filenames {
64
+ for entry in WalkDir :: new ( file) {
65
+ let entry = entry?;
66
+ if entry. file_type ( ) . is_file ( ) && entry. path ( ) . extension ( ) . unwrap_or_default ( ) == "cas"
67
+ {
68
+ let filename = entry. path ( ) . display ( ) . to_string ( ) ;
69
+ policy_files. push ( filename) ;
70
+ }
71
+ }
72
+ }
73
+ Ok ( policy_files)
74
+ }
0 commit comments