summaryrefslogtreecommitdiff
path: root/src/persist.rs
diff options
context:
space:
mode:
authorTyler Murphy <tylermurphy534@gmail.com>2022-11-09 10:49:25 -0500
committerTyler Murphy <tylermurphy534@gmail.com>2022-11-09 10:49:25 -0500
commit191632ce0ab810b4773f64eaf80ad67e87200c0b (patch)
tree51ff03bc25aba69142f0583e52d850424c619b55 /src/persist.rs
parentfix session pid, add uninstall sh file (diff)
downloadcrab-191632ce0ab810b4773f64eaf80ad67e87200c0b.tar.gz
crab-191632ce0ab810b4773f64eaf80ad67e87200c0b.tar.bz2
crab-191632ce0ab810b4773f64eaf80ad67e87200c0b.zip
help and version flags
Diffstat (limited to 'src/persist.rs')
-rw-r--r--src/persist.rs101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/persist.rs b/src/persist.rs
new file mode 100644
index 0000000..7d47232
--- /dev/null
+++ b/src/persist.rs
@@ -0,0 +1,101 @@
+use std::fs;
+use std::os::linux::fs::MetadataExt;
+use std::os::unix::prelude::PermissionsExt;
+use std::time::SystemTime;
+use nix::unistd;
+use serde_json::Value;
+
+const PERSIST_TIME: u64 = 60 * 3;
+
+pub fn get_persist(user: &str) -> bool {
+ let json = match get_terminal_config() {
+ Some(data) => data,
+ None => return false
+ };
+ let timestamp = match json[user].as_u64() {
+ Some(data) => data,
+ None => return false
+ };
+ return now() - timestamp < PERSIST_TIME;
+}
+
+pub fn set_persist(user: &str) {
+ let mut json = match get_terminal_config() {
+ Some(data) => data,
+ None => return
+ };
+ json[user] = Value::from(now());
+ let id = match get_terminal_process() {
+ Some(data) => data,
+ None => return
+ };
+ match write_terminal_config(&id, &json.to_string()) {
+ Ok(_) => {},
+ Err(e) => {
+ eprintln!("Internal Error: {}", e)
+ }
+ };
+}
+
+fn get_terminal_process() -> Option<i32> {
+ let id: i32 = match std::process::id().try_into() {
+ Ok(data) => data,
+ Err(_) => return None
+ };
+ let stat = match procinfo::pid::stat(id) {
+ Ok(data) => data,
+ Err(_) => return None
+ };
+ Some(stat.session)
+}
+
+fn is_file_root_only(id: &i32) -> bool {
+ let metadata = match std::fs::metadata(path(&id)) {
+ Ok(data) => data,
+ Err(e) => {
+ if let Some(err) = e.raw_os_error() {
+ return err == 2;
+ }
+ return true
+ }
+ };
+ let perms = metadata.permissions();
+ return perms.mode() == 33200 && metadata.st_uid() == 0 && metadata.st_gid() == 0;
+}
+
+fn get_terminal_config() -> Option<Value> {
+ let id = match get_terminal_process() {
+ Some(data) => data,
+ None => return None
+ };
+ if !is_file_root_only(&id) {
+ return None;
+ }
+ let data = match std::fs::read_to_string(path(&id)) {
+ Ok(data) => data,
+ Err(_) => "{}".to_string()
+ };
+ let json: Value = match serde_json::from_str(&data) {
+ Ok(data) => data,
+ Err(_) => return None
+ };
+ Some(json)
+}
+
+fn write_terminal_config(id: &i32, data: &str) -> Result<(), Box<dyn std::error::Error>> {
+ std::fs::write(path(&id), data)?;
+ unistd::chown(std::path::Path::new(&path(&id)), Some(unistd::Uid::from(0)), Some(unistd::Gid::from(0)))?;
+ let metadata = std::fs::metadata(path(&id))?;
+ let mut perms = metadata.permissions();
+ perms.set_mode(0o660);
+ fs::set_permissions(path(&id), perms)?;
+ Ok(())
+}
+
+fn now() -> u64 {
+ return SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
+}
+
+fn path(id: &i32) -> String {
+ return format!("/tmp/crab-{}", id);
+} \ No newline at end of file