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
use std::io;
use std::io::Read;
use std::fs::File;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::time::Duration;

use resolv_conf;


quick_error! {
    #[derive(Debug)]
    pub enum SystemConfigError {
        FileError(path: PathBuf, err: io::Error) {
            description("error parsing reading system config file")
            display("Error reading {:?}: {}", path, err)
            cause(err)
        }
        ResolvConf(err: resolv_conf::ParseError) {
            description("Error parsing resolv.conf")
            from()
        }
    }
}


pub struct Config {
    pub nameservers: Vec<SocketAddr>,
    pub timeout: Duration,
    pub attempts: u32,
}


impl Config {
    pub fn system() -> Result<Config, SystemConfigError> {
        use self::SystemConfigError::*;
        let mut buf = Vec::with_capacity(512);
        try!(File::open("/etc/resolv.conf")
            .and_then(|mut f| f.read_to_end(&mut buf))
            .map_err(|e| FileError("/etc/resolv.conf".into(), e)));
        let cfg = try!(resolv_conf::Config::parse(&buf));
        Ok(Config {
            nameservers: cfg.nameservers.iter()
                .map(|ns| SocketAddr::new(*ns, 53))
                .collect(),
            timeout: Duration::new(cfg.timeout.into(), 0),
            attempts: cfg.attempts.into(),
        })
    }
}