diff options
Diffstat (limited to 'src/client/executor')
| -rw-r--r-- | src/client/executor/tasks.rs | 108 |
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())) + } +} |
