diff --git a/Cargo.lock b/Cargo.lock index 9e1eefa6..86a8cbe5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,6 +178,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.38" @@ -506,11 +512,11 @@ dependencies = [ "crossterm", "ego-tree", "linutil_core", + "nix 0.29.0", "oneshot", "portable-pty", "rand", "ratatui", - "sudo", "temp-dir", "tree-sitter-bash", "tree-sitter-highlight", @@ -598,6 +604,18 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -677,7 +695,7 @@ dependencies = [ "lazy_static", "libc", "log", - "nix", + "nix 0.25.1", "serial", "shared_library", "shell-words", @@ -1007,16 +1025,6 @@ dependencies = [ "syn", ] -[[package]] -name = "sudo" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bd84d4c082e18e37fef52c0088e4407dabcef19d23a607fb4b5ee03b7d5b83" -dependencies = [ - "libc", - "log", -] - [[package]] name = "syn" version = "2.0.77" diff --git a/tui/Cargo.toml b/tui/Cargo.toml index d5532b11..f1f596bf 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -30,8 +30,8 @@ tree-sitter-highlight = "0.24.2" tree-sitter-bash = "0.23.1" anstyle = "1.0.8" ansi-to-tui = "6.0.0" -sudo = "0.6.0" zips = "0.1.7" +nix = { version = "0.29.0", features = [ "user" ] } [build-dependencies] chrono = "0.4.33" diff --git a/tui/src/main.rs b/tui/src/main.rs index 1433ddca..db0d3e27 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -3,6 +3,7 @@ mod filter; mod float; mod floating_text; mod hint; +mod root; mod running_command; pub mod state; mod theme; @@ -15,18 +16,12 @@ use std::{ use crate::theme::Theme; use clap::Parser; use crossterm::{ - event::{self, DisableMouseCapture, Event, KeyCode, KeyEvent, KeyEventKind}, + event::{self, DisableMouseCapture, Event, KeyEventKind}, style::ResetColor, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, ExecutableCommand, }; -use ratatui::{ - backend::CrosstermBackend, - layout::{Alignment, Constraint, Layout}, - style::Stylize, - widgets::{Paragraph, Wrap}, - Terminal, -}; +use ratatui::{backend::CrosstermBackend, Terminal}; use state::AppState; // Linux utility toolbox @@ -42,12 +37,6 @@ struct Args { } fn main() -> io::Result<()> { - if sudo::check() != sudo::RunningAs::User && !Args::parse().allow_root { - eprintln!("Error: This program is not intended to be run with elevated privileges."); - eprintln!("To bypass this restriction, use the '--allow-root' flag."); - std::process::exit(1); - } - let args = Args::parse(); let mut state = AppState::new(args.theme, args.override_validation); @@ -73,67 +62,8 @@ fn run( terminal: &mut Terminal>, state: &mut AppState, ) -> io::Result<()> { - if sudo::check() == sudo::RunningAs::Root { - terminal.draw(|frame| { - let root_warn = Paragraph::new( - r#" -!!!!!!!!!!!!!! YOU ARE ABOUT TO RUN LINUTIL AS ROOT !!!!!!!!!!!!!! - -This utility prioritizes compatibility with non-root environments. -Some scripts may work without any issues, some may not. -You have been warned! - -!!!!!!!!!!!!!!!!!!!!!! PROCEED WITH CAUTION !!!!!!!!!!!!!!!!!!!!!! - -Press [y] to continue, [n] to abort -"#, - ) - .on_black() - .white() - .alignment(Alignment::Center) - .wrap(Wrap { trim: true }); - - let rects = Layout::vertical([ - Constraint::Fill(1), - Constraint::Length(10), - Constraint::Fill(1), - ]) - .split(frame.area()); - - let centered = rects[1]; - - frame.render_widget(root_warn, centered); - })?; - - loop { - match event::read()? { - Event::Key( - KeyEvent { - code: KeyCode::Char('y'), - .. - } - | KeyEvent { - code: KeyCode::Char('Y'), - .. - }, - ) => { - break; - } - Event::Key( - KeyEvent { - code: KeyCode::Char('n'), - .. - } - | KeyEvent { - code: KeyCode::Char('N'), - .. - }, - ) => { - return Ok(()); - } - _ => {} - } - } + if !root::check_root(terminal)? { + return Ok(()); } loop { diff --git a/tui/src/root.rs b/tui/src/root.rs new file mode 100644 index 00000000..c8ba0b48 --- /dev/null +++ b/tui/src/root.rs @@ -0,0 +1,69 @@ +use ratatui::{ + backend::CrosstermBackend, + crossterm::event::{self, Event, KeyCode, KeyEvent}, + layout::{Alignment, Constraint, Layout}, + style::{Style, Stylize}, + widgets::{Paragraph, Wrap}, + Terminal, +}; +use std::io; + +pub fn check_root(terminal: &mut Terminal>) -> io::Result { + if nix::unistd::geteuid().is_root() { + terminal.draw(|frame| { + let root_warn = Paragraph::new( + r#" +!!!!!!!!!!!!!! YOU ARE ABOUT TO RUN LINUTIL AS ROOT !!!!!!!!!!!!!! +This utility prioritizes compatibility with non-root environments. +Some scripts may work without any issues, some may not. +You have been warned! +!!!!!!!!!!!!!!!!!!!!!! PROCEED WITH CAUTION !!!!!!!!!!!!!!!!!!!!!! +Press [y] to continue, [n] to abort +"#, + ) + .white() + .on_black() + .alignment(Alignment::Center) + .style(Style::default().bold()) + .wrap(Wrap { trim: true }); + + let rects = Layout::vertical([ + Constraint::Fill(1), + Constraint::Length(10), + Constraint::Fill(1), + ]) + .split(frame.area()); + + let centered = rects[1]; + + frame.render_widget(root_warn, centered); + })?; + + loop { + match event::read()? { + Event::Key( + KeyEvent { + code: KeyCode::Char('y'), + .. + } + | KeyEvent { + code: KeyCode::Char('Y'), + .. + }, + ) => break, + Event::Key( + KeyEvent { + code: KeyCode::Char('n'), + .. + } + | KeyEvent { + code: KeyCode::Char('N'), + .. + }, + ) => return Ok(false), + _ => {} + } + } + } + Ok(true) +}