use std::collections::HashMap;
use std::net;
use std::path;
use param;
use sys;
use JailError;
use RunningJail;
#[derive(Clone, PartialEq, Eq, Debug)]
#[cfg(target_os = "freebsd")]
pub struct StoppedJail {
pub path: Option<path::PathBuf>,
pub name: Option<String>,
pub hostname: Option<String>,
pub params: HashMap<String, param::Value>,
pub ips: Vec<net::IpAddr>,
}
#[cfg(target_os = "freebsd")]
impl Default for StoppedJail {
fn default() -> StoppedJail {
StoppedJail {
path: None,
name: None,
hostname: None,
params: HashMap::new(),
ips: vec![],
}
}
}
#[cfg(target_os = "freebsd")]
impl StoppedJail {
pub fn new<P: Into<path::PathBuf>>(path: P) -> StoppedJail {
let mut ret: StoppedJail = Default::default();
ret.path = Some(path.into());
ret
}
pub fn start(self: StoppedJail) -> Result<RunningJail, JailError> {
let path = match self.path {
None => return Err(JailError::PathNotGiven),
Some(ref p) => p.clone(),
};
let ret = sys::jail_create(
&path,
self.name.as_ref().map(String::as_str),
self.hostname.as_ref().map(String::as_str),
).map(RunningJail::from_jid)?;
let ip4s = param::Value::Ipv4Addrs(
self.ips
.iter()
.filter(|ip| ip.is_ipv4())
.map(|ip| match ip {
net::IpAddr::V4(ip4) => *ip4,
_ => panic!("unreachable"),
})
.collect(),
);
let ip6s = param::Value::Ipv6Addrs(
self.ips
.iter()
.filter(|ip| ip.is_ipv6())
.map(|ip| match ip {
net::IpAddr::V6(ip6) => *ip6,
_ => panic!("unreachable"),
})
.collect(),
);
param::set(ret.jid, "ip4.addr", ip4s)?;
param::set(ret.jid, "ip6.addr", ip6s)?;
for (param, value) in self.params {
param::set(ret.jid, ¶m, value)?;
}
Ok(ret)
}
pub fn name<S: Into<String>>(mut self: Self, name: S) -> Self {
self.name = Some(name.into());
self
}
pub fn hostname<S: Into<String>>(mut self: Self, hostname: S) -> Self {
self.hostname = Some(hostname.into());
self
}
pub fn param<S: Into<String>>(mut self: Self, param: S, value: param::Value) -> Self {
self.params.insert(param.into(), value);
self
}
pub fn ip(mut self: Self, ip: net::IpAddr) -> Self {
self.ips.push(ip);
self
}
}