#![warn(rust_2018_idioms)] mod config; mod message; use clap::{crate_version, Parser}; use gethostname::gethostname; use log::{error, info}; use std::net::IpAddr; use std::path::PathBuf; use std::process::exit; #[derive(Parser, Debug)] #[clap(name = "sendsms")] #[clap(author = "Franck Cuny ")] #[clap(version = crate_version!())] #[clap(propagate_version = true)] struct Args { #[clap(short, long, value_parser)] config: PathBuf, #[clap(subcommand)] subcmd: SubCommand, } #[derive(Parser, Debug)] enum SubCommand { Reboot, } fn main() { env_logger::init(); let args = Args::parse(); let config: config::Config = match config::Config::load_from_file(&args.config) { Ok(r) => r, Err(e) => { error!( "unable to load data from {}: {}", args.config.display(), e.to_string() ); exit(1); } }; let body = match args.subcmd { SubCommand::Reboot => reboot(&config.reboot), }; let msg = message::Message { from: config.from.to_owned(), to: config.to.to_owned(), body, }; match msg.send(&config) { Ok(_) => info!("message sent successfully"), Err(error) => { error!("failed to send the message: {}", error); exit(1); } } } fn reboot(config: &config::RebootConfig) -> String { let ipaddr_v4 = if_addrs::get_if_addrs() .unwrap_or_default() .into_iter() .find(|iface| iface.name == config.ifname) .and_then(|iface| match iface.ip() { IpAddr::V4(addr) => Some(addr), IpAddr::V6(_) => None, }) .expect("there should be an ipv4 address"); let hostname = gethostname() .into_string() .expect("failed to get the hostname"); format!( "{} has rebooted. The IP address for the interface {} is {}.", hostname, config.ifname, ipaddr_v4 ) }