From 94e6b3c7378f0147476e94d80005adf22b0ed73b Mon Sep 17 00:00:00 2001 From: TudbuT Date: Fri, 27 Oct 2023 00:43:45 +0200 Subject: [PATCH] Initial commit --- .gitignore | 1 + Cargo.lock | 7 ++++ Cargo.toml | 9 +++++ LICENSE | 45 +++++++++++++++++++++++ README.md | 15 ++++++++ src/main.rs | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 177 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..6c47328 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "dead_woman_switch" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..21f0550 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "dead_woman_switch" +version = "0.1.0" +edition = "2021" +authors = ["TudbuT", "JessSystemV"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3e70040 --- /dev/null +++ b/LICENSE @@ -0,0 +1,45 @@ +Strong Viral TudbuT License + +Copyright (c) 2023 Daniel H. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, and/or distribute copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +1. The above copyright notice, this permission notice, and these conditions + shall be included in all copies or substantial portions of the Software. + +2. The Software must not be (re-)sold or sublicensed without explicit written + permission from the copyright holder. + +3. When a significant modification is made and an executable, binary, or + similar source-code-derived artifact of this modified Software is + created and published or run in such a way that multiple people can use it, + the modified source code of that Software must be published under the same + license as the original. Other software which builds upon this Software + without modifying any existing part of it is included, so its source ALSO + needs to be published under the same license as this Software. + +4. Any improvement in or addition of speed, functionality, ease-of-use, + usability, or otherwise, is a significant modification. + +5. If this Software is a library, that is a collection of utilities that is + NOT an application by itself, or is marketed as such, and an application, + that is a piece of Software which the end-user directly interacts with in + order to do some task, or one which is run in a stand-alone fashion in + order to provide a service, is published or run in a way that multiple + people can use it, which uses a binary or similar source-code-derived + artifact of a significantly modified copy of this library, then that copy's + modified source code must be published under the same license as the + original, along with the source code of the application which uses it. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..91ea671 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Dead Woman's Switch + +A dead man's switch made to e-stop your linux PC when a drive is unplugged. + +Inspired by TailsOS, idea to make this by JessSystemV, written by TudbuT. + +``` +$ sudo dws /dev/sdb & disown +``` + +## Disclaimer + +I do not take any liability for any damages done by this software. Use this +only on PCs you don't mind losing data on. + diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..00aca8f --- /dev/null +++ b/src/main.rs @@ -0,0 +1,100 @@ +use std::{env, fs, io, path::Path, process, thread, time::Duration}; + +extern "C" { + fn kill(pid: i32, sig: core::ffi::c_int) -> core::ffi::c_int; + fn sync(); +} + +fn main() { + let argv = env::args().collect::>(); + + if argv.len() <= 1 { + help(); + unsafe { + kill(process::id() as i32, 15); + } + return; + } + + let dev = argv[1].to_owned(); + + let path = Path::new(dev.as_str()); + + if !path.exists() { + eprintln!("Device is not currently present. Exiting."); + return; + } + + #[cfg(debug_assertions)] + println!("Waiting for the file to die..."); + + while path.exists() { + thread::sleep(Duration::from_millis(5)); + } + + #[cfg(debug_assertions)] + println!("File died, killing system."); + + if kill_all().is_err() { + #[cfg(debug_assertions)] + println!("E-Stop due to error."); + thread::sleep(Duration::from_millis(500)); + unsafe { + sync(); + } + fs::write("/proc/sysrq-trigger", "o").unwrap(); + } +} + +fn help() { + println!("dead_woman_switch DEVFILE"); + println!(); + println!(" Kills the OS when a device is unplugged. "); +} + +fn kill_all() -> io::Result<()> { + let files = fs::read_dir("/proc/")? + .map(Result::unwrap) + .filter(|x| x.file_type().unwrap().is_dir()) + .filter(|x| { + x.file_name() + .to_str() + .unwrap() + .chars() + .all(|x| x.is_numeric()) + }) + .map(|x| x.file_name().into_string().unwrap().parse::().unwrap()) + .collect::>(); + + for process in &files { + let process = *process; + unsafe { + if process as u32 == process::id() { + continue; + } + kill(process, 15); + } + } + + thread::sleep(Duration::from_millis(200)); + + for process in &files { + let process = *process; + unsafe { + if process as u32 == process::id() { + continue; + } + kill(process, 9); + } + } + + unsafe { + sync(); + } + thread::sleep(Duration::from_millis(50)); + fs::write("/proc/sysrq-trigger", "u")?; + thread::sleep(Duration::from_millis(50)); + fs::write("/proc/sysrq-trigger", "o")?; + + Ok(()) +}