1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use graphviz;
use std::fmt;
use std::io;
use std::sync::Arc;
use stemflow::{FileAccess, ResPool};
use super::ArcDomain;
use super::profile::ProfileConfig;
pub struct Portal {
configs: Vec<ProfileConfig>,
pool: ResPool<Arc<FileAccess>>,
confined: bool,
}
impl Portal {
pub fn new(configs: Vec<ProfileConfig>, confined: bool) -> Portal {
let mut pool = ResPool::new();
for config in configs.iter() {
let _ = pool.new_dom(config.name.clone(), config.clone().into());
}
Portal {
configs: configs,
pool: pool,
confined: confined,
}
}
pub fn profile<T>(&self, name: T) -> Option<&ProfileConfig> where T: AsRef<str> {
self.configs.iter().find(|c| AsRef::<str>::as_ref(&c.name) == name.as_ref())
}
pub fn allow(&mut self, acl: &Vec<Arc<FileAccess>>) -> Option<ArcDomain> {
self.pool.allow(acl)
}
pub fn domain<T>(&mut self, name: T) -> Option<ArcDomain> where T: AsRef<str> {
let acl = match self.profile(name).map(|x| &x.fs.bind) {
Some(&Some(ref bind)) => {
let acl = bind.iter().map(|x| Into::<Vec<Arc<FileAccess>>>::into(x))
.flat_map(|x| x.into_iter()).collect();
Some(acl)
}
_ => None,
};
match acl {
Some(acl) => {
self.pool.allow(&acl)
}
_ => None,
}
}
pub fn render<T>(&self, out: &mut T) -> io::Result<()> where T: io::Write {
graphviz::render(&self.pool, out)
}
pub fn is_confined(&self) -> bool {
self.confined
}
}
impl fmt::Display for Portal {
fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
write!(out, "profiles: {:?}", self.configs.iter().map(|x| &x.name ).collect::<Vec<_>>())
}
}