1#[macro_use]
2extern crate error_chain;
3
4extern crate network_manager;
5
6use std::env;
7use std::process;
8use std::io::Write;
9
10use network_manager::{AccessPoint, AccessPointCredentials, Device, DeviceType, NetworkManager};
11
12mod errors {
13 use network_manager;
14
15 error_chain! {
16 links {
17 NetworkManager(network_manager::errors::Error, network_manager::errors::ErrorKind);
18 }
19
20 errors {
21 Runtime(info: String) {
22 description("Runtime error")
23 display("{}", info)
24 }
25 }
26 }
27}
28
29use errors::*;
30
31fn main() {
32 if let Err(ref e) = run() {
33 let stderr = &mut ::std::io::stderr();
34 let errmsg = "Error writing to stderr";
35
36 writeln!(stderr, "{}", e).expect(errmsg);
37
38 for e in e.iter().skip(1) {
39 writeln!(stderr, " caused by: {}", e).expect(errmsg);
40 }
41
42 ::std::process::exit(1);
43 }
44}
45
46fn run() -> Result<()> {
47 let args: Vec<String> = env::args().collect();
48
49 if args.len() != 3 {
50 println!("USAGE: create SSID PASSWORD");
51 process::exit(1);
52 }
53
54 let manager = NetworkManager::new();
55
56 let device = find_device(&manager)?;
57
58 let wifi_device = device.as_wifi_device().unwrap();
59
60 let access_points = wifi_device.get_access_points()?;
61
62 let ap_index = find_access_point(&access_points, &args[1] as &str)?;
63
64 let credentials = AccessPointCredentials::Wpa {
65 passphrase: args[2].clone(),
66 };
67
68 wifi_device.connect(&access_points[ap_index], &credentials)?;
69
70 Ok(())
71}
72
73fn find_device(manager: &NetworkManager) -> Result<Device> {
74 let devices = manager.get_devices()?;
75
76 let index = devices
77 .iter()
78 .position(|d| *d.device_type() == DeviceType::WiFi);
79
80 if let Some(index) = index {
81 Ok(devices[index].clone())
82 } else {
83 bail!(ErrorKind::Runtime("Cannot find a WiFi device".into()))
84 }
85}
86
87fn find_access_point(access_points: &[AccessPoint], ssid: &str) -> Result<usize> {
88 if let Some(index) = access_points.iter().position(|ap| same_ssid(ap, ssid)) {
89 Ok(index)
90 } else {
91 bail!(ErrorKind::Runtime("Access point not found".into()))
92 }
93}
94
95fn same_ssid(ap: &AccessPoint, ssid: &str) -> bool {
96 if let Ok(ap_ssid) = ap.ssid().as_str() {
97 ap_ssid == ssid
98 } else {
99 false
100 }
101}