diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2017-07-06 15:55:53 +0200 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2017-07-06 22:37:01 +0200 |
| commit | 239e101a91d67ee83d8f5e1c55cea60a095bbbaa (patch) | |
| tree | b65156026e4089c37c1d0ba1bf05b7f956d6a9e7 /mullvad_cli | |
| parent | 84ab812dfbbd6dae47eacc16d950d8856b1916be (diff) | |
| download | mullvadvpn-239e101a91d67ee83d8f5e1c55cea60a095bbbaa.tar.xz mullvadvpn-239e101a91d67ee83d8f5e1c55cea60a095bbbaa.zip | |
Renamed talpid_cli to mullvad_cli
Diffstat (limited to 'mullvad_cli')
| -rw-r--r-- | mullvad_cli/Cargo.toml | 17 | ||||
| -rw-r--r-- | mullvad_cli/src/cli.rs | 24 | ||||
| -rw-r--r-- | mullvad_cli/src/main.rs | 75 |
3 files changed, 116 insertions, 0 deletions
diff --git a/mullvad_cli/Cargo.toml b/mullvad_cli/Cargo.toml new file mode 100644 index 0000000000..5d758482c9 --- /dev/null +++ b/mullvad_cli/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "mullvad_cli" +version = "0.0.0" +authors = ["Linus Färnstrand <linus@mullvad.net>", "Erik Larkö <erik@mullvad.net>"] +description = "Run Talpid easily from the command line" + +[[bin]] +name = "mullvad" + +[dependencies] +clap = "2.20" +error-chain = "0.10" +log = "0.3" +env_logger = "0.4" +talpid_ipc = { path = "../talpid_ipc" } +serde = "1.0" +serde_json = "1.0" diff --git a/mullvad_cli/src/cli.rs b/mullvad_cli/src/cli.rs new file mode 100644 index 0000000000..c21e7f1562 --- /dev/null +++ b/mullvad_cli/src/cli.rs @@ -0,0 +1,24 @@ +use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; + +pub fn get_matches() -> ArgMatches<'static> { + let app = create_app(); + app.clone().get_matches() +} + +fn create_app() -> App<'static, 'static> { + App::new(crate_name!()) + .version(crate_version!()) + .author(crate_authors!()) + .about(crate_description!()) + .setting(AppSettings::SubcommandRequired) + .subcommand(SubCommand::with_name("account") + .about("Control and display information about the configured Mullvad account") + .setting(AppSettings::SubcommandRequired) + .subcommand(SubCommand::with_name("set") + .about("Change the Mullvad account") + .arg(Arg::with_name("token") + .help("The Mullvad account token to configure the daemon with") + .required(true))) + .subcommand(SubCommand::with_name("get") + .about("Display information about the currently configured account"))) +} diff --git a/mullvad_cli/src/main.rs b/mullvad_cli/src/main.rs new file mode 100644 index 0000000000..0d87173418 --- /dev/null +++ b/mullvad_cli/src/main.rs @@ -0,0 +1,75 @@ +// `error_chain!` can recurse deeply +#![recursion_limit = "1024"] + +extern crate talpid_ipc; +#[macro_use] +extern crate clap; +#[macro_use] +extern crate error_chain; +#[macro_use] +extern crate log; +extern crate env_logger; +extern crate serde; +extern crate serde_json; + +use std::fs::File; +use std::io::Read; + +mod cli; + + +error_chain!{} + +quick_main!(run); + +fn run() -> Result<()> { + env_logger::init().chain_err(|| "Failed to bootstrap logging system")?; + + let matches = cli::get_matches(); + if let Some(matches) = matches.subcommand_matches("account") { + cmd_account(matches) + } else { + unreachable!("No subcommand matches.") + } +} + +fn cmd_account(matches: &clap::ArgMatches) -> Result<()> { + if let Some(matches) = matches.subcommand_matches("set") { + let token = matches.value_of("token").unwrap(); + call_rpc("set_account", &[token]).map( + |_| { + println!("Mullvad account {} set", token); + }, + ) + } else if let Some(_matches) = matches.subcommand_matches("get") { + match call_rpc("get_account", &[] as &[u8; 0])? { + serde_json::Value::String(token) => println!("Mullvad account: {:?}", token), + serde_json::Value::Null => println!("No account configured"), + _ => bail!("Unable to fetch account token"), + } + Ok(()) + } else { + unreachable!("No account command given"); + } +} + +fn call_rpc<T>(method: &str, args: &T) -> Result<serde_json::Value> + where T: serde::Serialize +{ + let address = read_rpc_address()?; + info!("Using RPC address {}", address); + let mut rpc_client = talpid_ipc::WsIpcClient::new(address) + .chain_err(|| "Unable to create RPC client")?; + rpc_client.call(method, args).chain_err(|| "Unable to call RPC method") +} + +fn read_rpc_address() -> Result<String> { + for path in &["./.mullvad_rpc_address", "../.mullvad_rpc_address"] { + debug!("Trying to read RPC address at {}", path); + let mut address = String::new(); + if let Ok(_) = File::open(path).and_then(|mut file| file.read_to_string(&mut address)) { + return Ok(address); + } + } + bail!("Unable to read RPC address"); +} |
