Initial commit

This commit is contained in:
Daniella / Tove 2023-10-27 00:43:45 +02:00
commit 94e6b3c737
Signed by: TudbuT
GPG key ID: B3CF345217F202D3
6 changed files with 177 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

7
Cargo.lock generated Normal file
View file

@ -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"

9
Cargo.toml Normal file
View file

@ -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]

45
LICENSE Normal file
View file

@ -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.

15
README.md Normal file
View file

@ -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.

100
src/main.rs Normal file
View file

@ -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::<Vec<_>>();
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::<i32>().unwrap())
.collect::<Vec<_>>();
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(())
}