use std::io;
use piglog::prelude::*;
use fspp::*;
use colored::Colorize;
use crate::places;
use crate::proc;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum LockState {
Off,
OnOwned,
OnNotOwned,
}
pub fn lock_on() -> Result<(), io::Error> {
if is_lock_on() == false {
match file::write("", &lock_file_path()) {
Ok(_) => (),
Err(e) => {
piglog::error!("Failed to create locking file! ({e})");
return Err(e);
},
};
match file::write(&proc::get_proc_id(), &lock_file_owner_path()) {
Ok(_) => (),
Err(e) => {
piglog::error!("Failed to create and write locking owner file! ({e})");
return Err(e);
},
};
}
Ok(())
}
#[inline(always)]
pub fn lock_off() -> Result<(), io::Error> {
lock_off_core(false)
}
#[inline(always)]
pub fn lock_off_force() -> Result<(), io::Error> {
lock_off_core(true)
}
pub fn lock_off_core(force: bool) -> Result<(), io::Error> {
if force == false {
if lock_state()? != LockState::OnOwned {
return Ok(());
}
}
if is_lock_on_without_owner() {
match fs_action::delete(&lock_file_path()) {
Ok(_) => (),
Err(e) => {
piglog::error!("Failed to delete locking file! ({e})");
return Err(e);
},
};
match fs_action::delete(&lock_file_owner_path()) {
Ok(_) => (),
Err(e) => {
piglog::error!("Failed to delete locking owner file! ({e})");
return Err(e);
},
};
}
Ok(())
}
#[inline(always)]
pub fn lock_state() -> Result<LockState, io::Error> {
Ok(match (is_lock_on(), is_lock_on_without_owner()) {
(false, false) => LockState::Off,
(false, true) => LockState::OnOwned,
(true, true) => LockState::OnNotOwned,
_ => unreachable!(),
})
}
#[inline(always)]
pub fn is_lock_on() -> bool {
is_lock_on_core(true)
}
#[inline(always)]
fn is_lock_on_without_owner() -> bool {
is_lock_on_core(false)
}
fn is_lock_on_core(include_owner: bool) -> bool {
if lock_file_path().exists() {
if include_owner == false {
return true;
}
let owner = match file::read(&lock_file_owner_path()) {
Ok(o) => o,
Err(_) => return true,
};
let owner = owner.trim();
owner != proc::get_proc_id().trim()
}
else {
false
}
}
pub fn abort_if_locked() {
if is_lock_on() {
piglog::warning!("Rebos process lock detected... aborting...");
piglog::note!("If there are no other Rebos processes running, you can force unlock with the following command:");
piglog::note!("{} {}", "$:".bright_cyan().bold(), "rebos force-unlock".bright_magenta());
std::process::exit(1);
}
}
fn lock_file_path() -> Path {
places::base().add_str(".block_others_DO_NOT_DELETE_MANUALLY")
}
fn lock_file_owner_path() -> Path {
places::base().add_str(".owner_of_blocking_DO_NOT_DELETE_MANUALLY")
}