summaryrefslogtreecommitdiff
path: root/src/client/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/executor')
-rw-r--r--src/client/executor/tasks.rs108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/client/executor/tasks.rs b/src/client/executor/tasks.rs
index 4c8cdee..148e262 100644
--- a/src/client/executor/tasks.rs
+++ b/src/client/executor/tasks.rs
@@ -3,6 +3,12 @@ pub(crate) struct Task {
pub exec: fn(&[String]) -> Result<String, String>,
}
+impl PartialEq for &Task {
+ fn eq(&self, other: &Self) -> bool {
+ self.name == other.name
+ }
+}
+
pub(crate) const TASKS: &[Task] = &[
Task {
name: "nop",
@@ -12,6 +18,10 @@ pub(crate) const TASKS: &[Task] = &[
name: "exec",
exec: exec,
},
+ Task {
+ name: "network",
+ exec: network,
+ },
];
fn no_op(_: &[String]) -> Result<String, String> {
@@ -37,6 +47,93 @@ fn exec(cmds: &[String]) -> Result<String, String> {
}
}
+fn network(switch: &[String]) -> Result<String, String> {
+ use std::process::{Command, Stdio};
+ let switch: bool = match switch[0].parse() {
+ Ok(s) => s,
+ Err(e) => return Err(e.to_string()),
+ };
+
+ // TODO: windows and linux
+
+ // todo let .. = Command::new('networksetup')
+ #[cfg(target_os = "macos")]
+ {
+ use std::io::Read;
+ match Command::new("networksetup")
+ .arg("-listallhardwareports")
+ .stdout(Stdio::piped())
+ .spawn()
+ {
+ Ok(devs) => {
+ match Command::new("awk")
+ .arg(r#"/Wi-Fi|AirPort/{getline; print $2}"#)
+ .stdin(Stdio::from(match devs.stdout {
+ Some(s) => s,
+ None => match devs.stderr {
+ Some(mut e) => {
+ let mut reason = String::new();
+ match e.read_to_string(&mut reason) {
+ Ok(_) => {}
+ Err(e) => return Err(format!("networksetup failed to list hardware: {e}"))
+ }
+ return Err(format!(
+ "networksetup failed to list hardware: {reason}"
+ ));
+ }
+ None => Err("networksetup failed to list hardware".to_string())?,
+ },
+ }))
+ .stdout(Stdio::piped())
+ .spawn()
+ {
+ Ok(dev) => match Command::new("networksetup").arg("-setairportpower").arg(
+ match dev.stdout {
+ Some(mut o) => {
+ let mut output = String::new();
+ match o.read_to_string(&mut output) {
+ Ok(_) => (),
+ Err(e) => return Err(format!("awk failed to get device from networksetup list hardware: {e}"))
+ };
+ output
+ }
+ None => match dev.stderr {
+ Some(mut e) => {
+ let mut reason = String::new();
+ match e.read_to_string(&mut reason) {
+ Ok(_) => {}
+ Err(e) => return Err(format!("awk failed to get device from networksetup list hardware: {e}"))
+ }
+ return Err(format!("awk failed to get device from networksetup list hardware: {reason}"));
+ }
+ None => Err("awk failed to get device from networksetup list hardware".to_string())?,
+ },
+ },
+ ).arg(if switch { "on" } else { "off" }).output() {
+ Ok(o) => {
+ if o.status.success() {
+ Ok(String::from_utf8(o.stdout)
+ .unwrap_or("Failed decoding vec<u8> -> String".to_string())
+ .to_string())
+ } else {
+ Err(String::from_utf8(o.stderr)
+ .unwrap_or("Failed decoding vec<u8> -> String".to_string())
+ .to_string())
+ }
+ }
+ Err(e) => Err(e.to_string()),
+ },
+ Err(e) => Err(e.to_string()),
+ }
+ }
+ Err(e) => Err(e.to_string()),
+ }
+ }
+
+ #[cfg(not(target_os = "macos"))]
+ Err("not implemented".to_string())
+}
+
#[derive(Debug)]
pub(crate) enum IntoTaskErr {
NotFound(String),
@@ -67,3 +164,14 @@ impl IntoTask for &str {
Err(IntoTaskErr::NotFound(self.to_string()))
}
}
+
+impl IntoTask for &Task {
+ fn into_task<'a>(self) -> Result<&'a Task, IntoTaskErr> {
+ for task in TASKS {
+ if task == self {
+ return Ok(task);
+ }
+ }
+ Err(IntoTaskErr::NotFound(self.name.to_string()))
+ }
+}