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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
#![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 <franck@fcuny.net>")]
#[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
)
}
|