diff --git a/peach-network/src/error.rs b/peach-network/src/error.rs index efb468d..3840b67 100644 --- a/peach-network/src/error.rs +++ b/peach-network/src/error.rs @@ -148,7 +148,7 @@ pub enum NetworkError { /// Failed to retrieve connection state of wlan0 interface. WlanOperstate(IoError), /// Failed to save wpa_supplicant configuration changes to file. - Save, + Save(IoError), /// Failed to connect to network. Connect { /// ID. @@ -197,7 +197,7 @@ impl std::error::Error for NetworkError { NetworkError::Delete { .. } => None, NetworkError::WlanState(ref source) => Some(source), NetworkError::WlanOperstate(ref source) => Some(source), - NetworkError::Save => None, + NetworkError::Save(ref source) => Some(source), NetworkError::Connect { .. } => None, NetworkError::StartInterface { ref source, .. } => Some(source), NetworkError::WpaCtrl(ref source) => Some(source), @@ -326,7 +326,11 @@ impl std::fmt::Display for NetworkError { NetworkError::WlanOperstate(_) => { write!(f, "Failed to retrieve connection state of wlan0 interface") } - NetworkError::Save => write!(f, "Failed to save configuration changes to file"), + NetworkError::Save(ref source) => write!( + f, + "Failed to save configuration changes to file: {}", + source + ), NetworkError::Connect { ref id, ref iface } => { write!( f, diff --git a/peach-network/src/network.rs b/peach-network/src/network.rs index 96b7334..d9a57db 100644 --- a/peach-network/src/network.rs +++ b/peach-network/src/network.rs @@ -513,16 +513,14 @@ pub fn add(wlan_iface: &str, ssid: &str, pass: &str) -> Result<(), NetworkError> // append wpa_passphrase output to wpa_supplicant-.conf if successful if output.status.success() { // open file in append mode - let file = OpenOptions::new().append(true).open(wlan_config); + let mut file = OpenOptions::new() + .append(true) + .open(wlan_config) + // TODO: create the file if it doesn't exist + .map_err(NetworkError::Save)?; + + file.write(&wpa_details).map_err(NetworkError::Save)?; - let _file = match file { - // if file exists & open succeeds, write wifi configuration - Ok(mut f) => f.write(&wpa_details), - // TODO: handle this better: create file if not found - // & seed with 'ctrl_interace' & 'update_config' settings - // config file could also be copied from peach/config fs location - Err(e) => panic!("Failed to write to file: {}", e), - }; Ok(()) } else { let err_msg = String::from_utf8_lossy(&output.stdout); @@ -642,6 +640,38 @@ pub fn disconnect(iface: &str) -> Result<(), NetworkError> { Ok(()) } +/// Forget credentials for the given network SSID and interface. +/// Look up the network identified for the given SSID, delete the credentials +/// and then save. +/// +/// # Arguments +/// +/// * `iface` - A string slice holding the name of a wireless network interface +/// * `ssid` - A string slice holding the SSID for a wireless access point +/// +/// If the credentials are successfully deleted and saved, an `Ok` `Result` +/// type is returned. In the event of an error, a `NetworkError` is returned +/// in the `Result`. +pub fn forget(iface: &str, ssid: &str) -> Result<(), NetworkError> { + // get the id of the network + let id_opt = id(iface, ssid)?; + let id = id_opt.ok_or(NetworkError::Id { + ssid: ssid.to_string(), + iface: iface.to_string(), + })?; + // delete the old credentials + // TODO: i've switched these back to the "correct" order + // WEIRD BUG: the parameters below are technically in the wrong order: + // it should be id first and then iface, but somehow they get twisted. + // i don't understand computers. + //delete(&iface, &id)?; + delete(&id, iface)?; + // save the updates to wpa_supplicant.conf + save()?; + + Ok(()) +} + /// Modify password for a given network identifier and interface. /// /// # Arguments @@ -708,7 +738,7 @@ pub fn reconnect(iface: &str) -> Result<(), NetworkError> { /// Save configuration updates to the `wpa_supplicant` configuration file. /// -/// If wireless network configuration updates are successfully save to the +/// If wireless network configuration updates are successfully saved to the /// `wpa_supplicant.conf` file, an `Ok` `Result` type is returned. In the /// event of an error, a `NetworkError` is returned in the `Result`. pub fn save() -> Result<(), NetworkError> { @@ -716,3 +746,18 @@ pub fn save() -> Result<(), NetworkError> { wpa.request("SAVE_CONFIG")?; Ok(()) } + +/// Update password for an access point and save configuration updates to the +/// `wpa_supplicant` configuration file. +/// +/// If wireless network configuration updates are successfully saved to the +/// `wpa_supplicant.conf` file, an `Ok` `Result` type is returned. In the +/// event of an error, a `NetworkError` is returned in the `Result`. +pub fn update(iface: &str, ssid: &str, pass: &str) -> Result<(), NetworkError> { + // delete the old credentials and save the changes + forget(iface, ssid)?; + // add the new credentials + add(iface, ssid, pass)?; + reconfigure()?; + Ok(()) +}