101 lines
2.3 KiB
Rust
101 lines
2.3 KiB
Rust
use std::sync::Arc;
|
|
|
|
use ntex::{
|
|
http::StatusCode,
|
|
web::{self, App, HttpServer, Responder, types::State},
|
|
};
|
|
|
|
mod error;
|
|
|
|
type Result<T> = core::result::Result<T, error::ErrorWrapper>;
|
|
|
|
#[derive(Debug, Clone)]
|
|
struct Config {
|
|
doas: Option<Arc<String>>,
|
|
}
|
|
|
|
#[ntex::main]
|
|
async fn main() -> std::io::Result<()> {
|
|
let bind = std::env::var("BIND").unwrap_or("127.0.0.1:5544".to_owned());
|
|
let cfg = Config {
|
|
doas: std::env::var("DOAS").map(Arc::new).ok(),
|
|
};
|
|
|
|
HttpServer::new(move || {
|
|
App::new()
|
|
.service(root)
|
|
.service(poweroff)
|
|
.service(ping)
|
|
.service(clients)
|
|
.service(temp)
|
|
.state(cfg.clone())
|
|
})
|
|
.bind(bind)?
|
|
.run()
|
|
.await
|
|
}
|
|
|
|
#[web::get("/")]
|
|
async fn root() -> impl Responder {
|
|
include_bytes!("../static/index.html")
|
|
.with_header("content-type", "text/html")
|
|
.with_status(StatusCode::OK)
|
|
}
|
|
|
|
#[web::get("/off")]
|
|
async fn poweroff(cfg: State<Config>) -> Result<impl Responder> {
|
|
const EXE: &str = "/sbin/poweroff";
|
|
|
|
let mut cmd = if let Some(doas) = &cfg.doas {
|
|
let mut cmd = tokio::process::Command::new(&**doas);
|
|
cmd.arg(EXE);
|
|
cmd
|
|
} else {
|
|
tokio::process::Command::new(EXE)
|
|
};
|
|
|
|
cmd.kill_on_drop(false).spawn()?;
|
|
|
|
Ok("OK")
|
|
}
|
|
|
|
#[web::get("/ping")]
|
|
async fn ping() -> Result<impl Responder> {
|
|
let out = tokio::process::Command::new("/bin/ping")
|
|
.arg("-c")
|
|
.arg("4")
|
|
.arg("1.1.1.1")
|
|
.output()
|
|
.await?;
|
|
|
|
Ok(format!(
|
|
"exited with {}\n\nstdout:\n{}\n----\n\nstderr:\n{}",
|
|
out.status,
|
|
String::from_utf8_lossy(&out.stdout),
|
|
String::from_utf8_lossy(&out.stderr),
|
|
))
|
|
}
|
|
|
|
#[web::get("/ips")]
|
|
async fn clients() -> Result<impl Responder> {
|
|
tokio::fs::read_to_string("/var/lib/misc/dnsmasq.leases")
|
|
.await
|
|
.map_err(Into::into)
|
|
}
|
|
|
|
#[web::get("/temp")]
|
|
async fn temp(cfg: State<Config>) -> Result<impl Responder> {
|
|
const EXE: &str = "/usr/bin/vcgencmd";
|
|
|
|
let mut cmd = if let Some(doas) = &cfg.doas {
|
|
let mut cmd = tokio::process::Command::new(&**doas);
|
|
cmd.arg(EXE);
|
|
cmd
|
|
} else {
|
|
tokio::process::Command::new(EXE)
|
|
};
|
|
|
|
let out = cmd.arg("measure_temp").output().await?;
|
|
|
|
Ok(String::from_utf8(out.stdout)?)
|
|
}
|