From a9146e1702a7caa400acafeec96d5dd0604fa35b Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 3 Nov 2024 16:39:14 +1100 Subject: [PATCH 1/9] 03/11/24 adding doas --- src/exec.rs | 46 ++++++++++++++++++++++++++++++---------------- src/lib.rs | 3 ++- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/exec.rs b/src/exec.rs index 8e3a58ef..48e1a622 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -4,7 +4,7 @@ use crate::config::Config; use std::ffi::OsStr; use std::fmt::{Debug, Display, Formatter}; use std::path::Path; -use std::process::{Command, Output, Stdio}; +use std::process::{Command, Output}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::Arc; use std::thread; @@ -88,6 +88,22 @@ fn command_err(cmd: &Command) -> String { .join(" ") ) } +pub fn get_privileged_command() -> String { + println!("Looking for doas..."); + if Command::new("doas").output().is_ok() { + println!("Found doas."); + "doas".to_string() + } else { + println!("doas not found. Falling back to sudo."); + "sudo".to_string() + } +} + +pub fn spawn_sudo(sudo: String, flags: Vec) -> Result<()> { + update_sudo(&sudo, &flags)?; + thread::spawn(move || sudo_loop(&sudo, &flags)); + Ok(()) +} fn command_status(cmd: &mut Command) -> Result { debug!("running command: {:?}", cmd); @@ -98,7 +114,7 @@ fn command_status(cmd: &mut Command) -> Result { let ret = cmd .status() .map(|s| Status(s.code().unwrap_or(1))) - .with_context(|| command_err(cmd)); + .context(|| command_err(cmd)()); DEFAULT_SIGNALS.store(true, Ordering::Relaxed); @@ -110,9 +126,7 @@ fn command_status(cmd: &mut Command) -> Result { pub fn command(cmd: &mut Command) -> Result<()> { debug!("running command: {:?}", cmd); - command_status(cmd)? - .success() - .with_context(|| command_err(cmd))?; + command_status(cmd)?; Ok(()) } @@ -141,21 +155,22 @@ pub fn command_output(cmd: &mut Command) -> Result { Ok(ret) } -pub fn spawn_sudo(sudo: String, flags: Vec) -> Result<()> { - update_sudo(&sudo, &flags)?; - thread::spawn(move || sudo_loop(&sudo, &flags)); +pub fn spawn_privileged_command(flags: Vec) -> Result<()> { + let privileged_cmd = get_privileged_command(); + update_privileged_command(&privileged_cmd, &flags)?; + thread::spawn(move || privileged_command_loop(&privileged_cmd, &flags)); Ok(()) } -fn sudo_loop>(sudo: &str, flags: &[S]) -> Result<()> { +fn privileged_command_loop>(privileged_cmd: &str, flags: &[S]) -> Result<()> { loop { thread::sleep(Duration::from_secs(250)); - update_sudo(sudo, flags)?; + update_privileged_command(privileged_cmd, flags)?; } } -fn update_sudo>(sudo: &str, flags: &[S]) -> Result<()> { - let mut cmd = Command::new(sudo); +fn update_privileged_command>(privileged_cmd: &str, flags: &[S]) -> Result<()> { + let mut cmd = Command::new(privileged_cmd); cmd.args(flags); let status = command_status(&mut cmd)?; status.success()?; @@ -169,8 +184,7 @@ fn wait_for_lock(config: &Config) { println!( "{} {}", c.error.paint("::"), - c.bold - .paint(tr!("Pacman is currently in use, please wait...")) + c.bold.paint(tr!("Pacman is currently in use, please wait...")) ); while path.exists() { @@ -179,10 +193,11 @@ fn wait_for_lock(config: &Config) { } } + fn new_pacman + Display + Debug>(config: &Config, args: &Args) -> Command { let mut cmd = if config.need_root { wait_for_lock(config); - let mut cmd = Command::new(&config.sudo_bin); + let mut cmd = Command::new(&get_privileged_command()); cmd.args(&config.sudo_flags).arg(args.bin.as_ref()); cmd } else { @@ -206,7 +221,6 @@ pub fn pacman_output + Display + std::fmt::Debug>( args: &Args, ) -> Result { let mut cmd = new_pacman(config, args); - cmd.stdin(Stdio::inherit()); command_output(&mut cmd) } diff --git a/src/lib.rs b/src/lib.rs index d0258140..f3e2c7f3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,6 +39,7 @@ extern crate smart_default; use crate::chroot::Chroot; use crate::config::{Config, Op}; use crate::query::print_upgrade_list; +use crate::exec::Status; use std::collections::HashMap; use std::env::{self, current_dir}; @@ -91,7 +92,7 @@ fn print_error(color: Style, err: Error) { let mut iter = err.chain().peekable(); if ::is::(*iter.peek().unwrap()) - || ::is::(*iter.peek().unwrap()) + || ::is::(*iter.peek().unwrap()) { eprint!("{}", iter.peek().unwrap()); return; From 9574e848c952de8791bad473708260cc75d1d093 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 3 Nov 2024 16:57:51 +1100 Subject: [PATCH 2/9] 03/11/24 adding doas --- src/exec.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/exec.rs b/src/exec.rs index 48e1a622..fde480e3 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -105,6 +105,23 @@ pub fn spawn_sudo(sudo: String, flags: Vec) -> Result<()> { Ok(()) } +fn update_sudo(sudo: &str, flags: &[String]) -> Result<()> { + let mut cmd = Command::new(sudo); + cmd.args(flags); + let status = command_status(&mut cmd)?; + status.success()?; + Ok(()) +} + +fn sudo_loop(sudo: &str, flags: &[String]) { + loop { + thread::sleep(Duration::from_secs(250)); + if let Err(e) = update_sudo(sudo, flags) { + eprintln!("Failed to update sudo: {}", e); + } + } +} + fn command_status(cmd: &mut Command) -> Result { debug!("running command: {:?}", cmd); let term = &*CAUGHT_SIGNAL; @@ -114,7 +131,7 @@ fn command_status(cmd: &mut Command) -> Result { let ret = cmd .status() .map(|s| Status(s.code().unwrap_or(1))) - .context(|| command_err(cmd)()); + .context(|| command_err(cmd).to_string()); DEFAULT_SIGNALS.store(true, Ordering::Relaxed); From 826a2d3aa3636e7d6c36d4ab5058bc2818ebd11f Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 3 Nov 2024 17:22:09 +1100 Subject: [PATCH 3/9] 03/11/24 adding doas --- src/exec.rs | 63 ++++++++++++++--------------------------------------- src/lib.rs | 3 +-- 2 files changed, 17 insertions(+), 49 deletions(-) diff --git a/src/exec.rs b/src/exec.rs index fde480e3..8e3a58ef 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -4,7 +4,7 @@ use crate::config::Config; use std::ffi::OsStr; use std::fmt::{Debug, Display, Formatter}; use std::path::Path; -use std::process::{Command, Output}; +use std::process::{Command, Output, Stdio}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::Arc; use std::thread; @@ -88,39 +88,6 @@ fn command_err(cmd: &Command) -> String { .join(" ") ) } -pub fn get_privileged_command() -> String { - println!("Looking for doas..."); - if Command::new("doas").output().is_ok() { - println!("Found doas."); - "doas".to_string() - } else { - println!("doas not found. Falling back to sudo."); - "sudo".to_string() - } -} - -pub fn spawn_sudo(sudo: String, flags: Vec) -> Result<()> { - update_sudo(&sudo, &flags)?; - thread::spawn(move || sudo_loop(&sudo, &flags)); - Ok(()) -} - -fn update_sudo(sudo: &str, flags: &[String]) -> Result<()> { - let mut cmd = Command::new(sudo); - cmd.args(flags); - let status = command_status(&mut cmd)?; - status.success()?; - Ok(()) -} - -fn sudo_loop(sudo: &str, flags: &[String]) { - loop { - thread::sleep(Duration::from_secs(250)); - if let Err(e) = update_sudo(sudo, flags) { - eprintln!("Failed to update sudo: {}", e); - } - } -} fn command_status(cmd: &mut Command) -> Result { debug!("running command: {:?}", cmd); @@ -131,7 +98,7 @@ fn command_status(cmd: &mut Command) -> Result { let ret = cmd .status() .map(|s| Status(s.code().unwrap_or(1))) - .context(|| command_err(cmd).to_string()); + .with_context(|| command_err(cmd)); DEFAULT_SIGNALS.store(true, Ordering::Relaxed); @@ -143,7 +110,9 @@ fn command_status(cmd: &mut Command) -> Result { pub fn command(cmd: &mut Command) -> Result<()> { debug!("running command: {:?}", cmd); - command_status(cmd)?; + command_status(cmd)? + .success() + .with_context(|| command_err(cmd))?; Ok(()) } @@ -172,22 +141,21 @@ pub fn command_output(cmd: &mut Command) -> Result { Ok(ret) } -pub fn spawn_privileged_command(flags: Vec) -> Result<()> { - let privileged_cmd = get_privileged_command(); - update_privileged_command(&privileged_cmd, &flags)?; - thread::spawn(move || privileged_command_loop(&privileged_cmd, &flags)); +pub fn spawn_sudo(sudo: String, flags: Vec) -> Result<()> { + update_sudo(&sudo, &flags)?; + thread::spawn(move || sudo_loop(&sudo, &flags)); Ok(()) } -fn privileged_command_loop>(privileged_cmd: &str, flags: &[S]) -> Result<()> { +fn sudo_loop>(sudo: &str, flags: &[S]) -> Result<()> { loop { thread::sleep(Duration::from_secs(250)); - update_privileged_command(privileged_cmd, flags)?; + update_sudo(sudo, flags)?; } } -fn update_privileged_command>(privileged_cmd: &str, flags: &[S]) -> Result<()> { - let mut cmd = Command::new(privileged_cmd); +fn update_sudo>(sudo: &str, flags: &[S]) -> Result<()> { + let mut cmd = Command::new(sudo); cmd.args(flags); let status = command_status(&mut cmd)?; status.success()?; @@ -201,7 +169,8 @@ fn wait_for_lock(config: &Config) { println!( "{} {}", c.error.paint("::"), - c.bold.paint(tr!("Pacman is currently in use, please wait...")) + c.bold + .paint(tr!("Pacman is currently in use, please wait...")) ); while path.exists() { @@ -210,11 +179,10 @@ fn wait_for_lock(config: &Config) { } } - fn new_pacman + Display + Debug>(config: &Config, args: &Args) -> Command { let mut cmd = if config.need_root { wait_for_lock(config); - let mut cmd = Command::new(&get_privileged_command()); + let mut cmd = Command::new(&config.sudo_bin); cmd.args(&config.sudo_flags).arg(args.bin.as_ref()); cmd } else { @@ -238,6 +206,7 @@ pub fn pacman_output + Display + std::fmt::Debug>( args: &Args, ) -> Result { let mut cmd = new_pacman(config, args); + cmd.stdin(Stdio::inherit()); command_output(&mut cmd) } diff --git a/src/lib.rs b/src/lib.rs index f3e2c7f3..d0258140 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,6 @@ extern crate smart_default; use crate::chroot::Chroot; use crate::config::{Config, Op}; use crate::query::print_upgrade_list; -use crate::exec::Status; use std::collections::HashMap; use std::env::{self, current_dir}; @@ -92,7 +91,7 @@ fn print_error(color: Style, err: Error) { let mut iter = err.chain().peekable(); if ::is::(*iter.peek().unwrap()) - || ::is::(*iter.peek().unwrap()) + || ::is::(*iter.peek().unwrap()) { eprint!("{}", iter.peek().unwrap()); return; From 2e2a440049be08c4b579192e0d622f0f3669b836 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 3 Nov 2024 17:33:52 +1100 Subject: [PATCH 4/9] adding doas --- src/exec.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/exec.rs b/src/exec.rs index 8e3a58ef..34c9ff51 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -89,6 +89,62 @@ fn command_err(cmd: &Command) -> String { ) } +pub fn get_privileged_command() -> String { + if Command::new("doas").output().is_ok() { + "doas".to_string() + } else if Command::new("run0").output().is_ok() { + "run0".to_string() + } else { + "sudo".to_string() + } +} + +pub fn spawn_privileged_command(flags: Vec) -> Result<()> { + let privileged_cmd = get_privileged_command(); + match privileged_cmd.as_str() { + "doas" | "sudo" => { + update_privileged_command(&privileged_cmd, &flags)?; + thread::spawn(move || privileged_command_loop(&privileged_cmd, &flags)); + } + "run0" => { + update_run0(&flags)?; + thread::spawn(move || { + loop { + thread::sleep(Duration::from_secs(250)); + if let Err(e) = update_run0(&flags) { + eprintln!("Failed to update run0: {}", e); + } + } + }); + } + _ => {} + } + Ok(()) +} + +fn update_privileged_command>(privileged_cmd: &str, flags: &[S]) -> Result<()> { + let mut cmd = Command::new(privileged_cmd); + cmd.args(flags); + let status = command_status(&mut cmd)?; + status.success()?; + Ok(()) +} + +fn update_run0>(flags: &[S]) -> Result<()> { + let mut cmd = Command::new("run0"); + cmd.args(flags); + let status = command_status(&mut cmd)?; + status.success()?; + Ok(()) +} + +fn privileged_command_loop>(privileged_cmd: &str, flags: &[S]) -> Result<()> { + loop { + thread::sleep(Duration::from_secs(250)); + update_privileged_command(privileged_cmd, flags)?; + } +} + fn command_status(cmd: &mut Command) -> Result { debug!("running command: {:?}", cmd); let term = &*CAUGHT_SIGNAL; From a8b1a28ab491b00f4a1ba63e14f29ed4bae27ae6 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 3 Nov 2024 17:41:49 +1100 Subject: [PATCH 5/9] adding doas --- src/exec.rs | 2 +- src/install.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/exec.rs b/src/exec.rs index 34c9ff51..4ab06b4d 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -238,7 +238,7 @@ fn wait_for_lock(config: &Config) { fn new_pacman + Display + Debug>(config: &Config, args: &Args) -> Command { let mut cmd = if config.need_root { wait_for_lock(config); - let mut cmd = Command::new(&config.sudo_bin); + let mut cmd = Command::new(&get_privileged_command()); cmd.args(&config.sudo_flags).arg(args.bin.as_ref()); cmd } else { diff --git a/src/install.rs b/src/install.rs index 815959fa..ca20d08b 100644 --- a/src/install.rs +++ b/src/install.rs @@ -141,7 +141,7 @@ impl Installer { if !config.sudo_loop.is_empty() { let mut flags = config.sudo_flags.clone(); flags.extend(config.sudo_loop.clone()); - exec::spawn_sudo(config.sudo_bin.clone(), flags)?; + exec::spawn_privileged_command(config.sudo_bin.clone(), flags)?; } Ok(()) } From d4e1df5c54b1e8b226021c8b2ced71e42585fd99 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 3 Nov 2024 17:55:00 +1100 Subject: [PATCH 6/9] adding doas --- src/config.rs | 6 +++- src/exec.rs | 83 ++++++++++++++------------------------------------- 2 files changed, 27 insertions(+), 62 deletions(-) diff --git a/src/config.rs b/src/config.rs index 8aea84b1..7b325981 100644 --- a/src/config.rs +++ b/src/config.rs @@ -437,7 +437,6 @@ pub struct Config { pub mode: Mode, pub aur_filter: bool, pub interactive: bool, - #[default = 7] pub completion_interval: u64, @@ -536,6 +535,9 @@ pub struct Config { pub ignore: Vec, pub ignore_group: Vec, pub ignore_devel_source: Vec, + #[default = "doas"] + pub doas_bin: String, + pub doas_flags: Vec, #[default(GlobSet::empty())] pub ignore_devel: GlobSet, #[default(GlobSetBuilder::new())] @@ -1002,6 +1004,8 @@ impl Config { "Pacman" => self.pacman_bin = value, "PacmanConf" => self.pacman_conf_bin = Some(value), "Git" => self.git_bin = value, + "Doas" => self.doas_bin = value, + "DoasFlags" => self.doas_flags.extend(split), "Pkgctl" => self.pkgctl_bin = value, "Gpg" => self.gpg_bin = value, "Sudo" => self.sudo_bin = value, diff --git a/src/exec.rs b/src/exec.rs index 4ab06b4d..7531d07c 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -92,8 +92,6 @@ fn command_err(cmd: &Command) -> String { pub fn get_privileged_command() -> String { if Command::new("doas").output().is_ok() { "doas".to_string() - } else if Command::new("run0").output().is_ok() { - "run0".to_string() } else { "sudo".to_string() } @@ -101,49 +99,26 @@ pub fn get_privileged_command() -> String { pub fn spawn_privileged_command(flags: Vec) -> Result<()> { let privileged_cmd = get_privileged_command(); - match privileged_cmd.as_str() { - "doas" | "sudo" => { - update_privileged_command(&privileged_cmd, &flags)?; - thread::spawn(move || privileged_command_loop(&privileged_cmd, &flags)); - } - "run0" => { - update_run0(&flags)?; - thread::spawn(move || { - loop { - thread::sleep(Duration::from_secs(250)); - if let Err(e) = update_run0(&flags) { - eprintln!("Failed to update run0: {}", e); - } - } - }); - } - _ => {} - } + update_privileged_command(&privileged_cmd, &flags)?; + thread::spawn(move || privileged_command_loop(&privileged_cmd, &flags)); Ok(()) } -fn update_privileged_command>(privileged_cmd: &str, flags: &[S]) -> Result<()> { - let mut cmd = Command::new(privileged_cmd); - cmd.args(flags); - let status = command_status(&mut cmd)?; - status.success()?; - Ok(()) +fn privileged_command_loop>(cmd: &str, flags: &[S]) -> Result<()> { + loop { + thread::sleep(Duration::from_secs(250)); + update_privileged_command(cmd, flags)?; + } } -fn update_run0>(flags: &[S]) -> Result<()> { - let mut cmd = Command::new("run0"); +fn update_privileged_command>(cmd: &str, flags: &[S]) -> Result<()> { + let mut cmd = Command::new(cmd); cmd.args(flags); let status = command_status(&mut cmd)?; status.success()?; Ok(()) } -fn privileged_command_loop>(privileged_cmd: &str, flags: &[S]) -> Result<()> { - loop { - thread::sleep(Duration::from_secs(250)); - update_privileged_command(privileged_cmd, flags)?; - } -} fn command_status(cmd: &mut Command) -> Result { debug!("running command: {:?}", cmd); @@ -197,27 +172,6 @@ pub fn command_output(cmd: &mut Command) -> Result { Ok(ret) } -pub fn spawn_sudo(sudo: String, flags: Vec) -> Result<()> { - update_sudo(&sudo, &flags)?; - thread::spawn(move || sudo_loop(&sudo, &flags)); - Ok(()) -} - -fn sudo_loop>(sudo: &str, flags: &[S]) -> Result<()> { - loop { - thread::sleep(Duration::from_secs(250)); - update_sudo(sudo, flags)?; - } -} - -fn update_sudo>(sudo: &str, flags: &[S]) -> Result<()> { - let mut cmd = Command::new(sudo); - cmd.args(flags); - let status = command_status(&mut cmd)?; - status.success()?; - Ok(()) -} - fn wait_for_lock(config: &Config) { let path = Path::new(config.alpm.dbpath()).join("db.lck"); let c = config.color; @@ -236,14 +190,21 @@ fn wait_for_lock(config: &Config) { } fn new_pacman + Display + Debug>(config: &Config, args: &Args) -> Command { - let mut cmd = if config.need_root { - wait_for_lock(config); - let mut cmd = Command::new(&get_privileged_command()); - cmd.args(&config.sudo_flags).arg(args.bin.as_ref()); +let mut cmd = if config.need_root { + wait_for_lock(config); + let cmd = if Path::new("/usr/bin/doas").exists() { + let mut cmd = Command::new(&config.doas_bin); + cmd.args(&config.doas_flags).arg(args.bin.as_ref()); cmd } else { - Command::new(args.bin.as_ref()) - }; + let mut cmd = Command::new(&config.sudo_bin); + cmd.args(&config.sudo_flags).arg(args.bin.as_ref()); + cmd + }; + cmd +} else { + Command::new(args.bin.as_ref()) +}; if let Some(config) = &config.pacman_conf { cmd.args(["--config", config]); From d40ca6c7fcf7cdde8a31d522b456d09b1ece7a92 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 3 Nov 2024 17:58:00 +1100 Subject: [PATCH 7/9] adding doas --- src/install.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/install.rs b/src/install.rs index ca20d08b..12144c0f 100644 --- a/src/install.rs +++ b/src/install.rs @@ -141,7 +141,9 @@ impl Installer { if !config.sudo_loop.is_empty() { let mut flags = config.sudo_flags.clone(); flags.extend(config.sudo_loop.clone()); - exec::spawn_privileged_command(config.sudo_bin.clone(), flags)?; + let mut privilege_flags = vec![config.sudo_bin.clone()]; + privilege_flags.extend(flags); + exec::spawn_privileged_command(privilege_flags)?; } Ok(()) } From 7222031bbbd73281a38e92bc6b0f060cd1a9ad9e Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 3 Nov 2024 18:30:00 +1100 Subject: [PATCH 8/9] added doas functionality --- src/install.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/install.rs b/src/install.rs index 12144c0f..21ee4e35 100644 --- a/src/install.rs +++ b/src/install.rs @@ -27,6 +27,7 @@ use crate::{args, exec, news, print_error, printtr, repo}; use alpm::{Alpm, Depend, Version}; use alpm_utils::depends::{satisfies, satisfies_nover, satisfies_provide, satisfies_provide_nover}; use alpm_utils::{DbListExt, Targ}; + use ansi_term::Style; use anyhow::{bail, ensure, Context, Result}; use aur_depends::{Actions, Base, Conflict, DepMissing, RepoPackage}; From ab5c4485c3ac481393dbb7d01b475c7c5e941ebd Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 3 Nov 2024 18:50:17 +1100 Subject: [PATCH 9/9] 03/11/24 adding doas --- src/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index 7b325981..5036dd67 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1004,11 +1004,10 @@ impl Config { "Pacman" => self.pacman_bin = value, "PacmanConf" => self.pacman_conf_bin = Some(value), "Git" => self.git_bin = value, - "Doas" => self.doas_bin = value, - "DoasFlags" => self.doas_flags.extend(split), "Pkgctl" => self.pkgctl_bin = value, "Gpg" => self.gpg_bin = value, "Sudo" => self.sudo_bin = value, + "Doas" => self.doas_bin = value, "Pager" => self.pager_cmd = Some(value), "Bat" => self.bat_bin = value, "FileManager" => self.fm = Some(value), @@ -1016,6 +1015,7 @@ impl Config { "GitFlags" => self.git_flags.extend(split), "GpgFlags" => self.gpg_flags.extend(split), "SudoFlags" => self.sudo_flags.extend(split), + "DoasFlags" => self.doas_flags.extend(split), "BatFlags" => self.bat_flags.extend(split), "FileManagerFlags" => self.fm_flags.extend(split), "ChrootFlags" => self.chroot_flags.extend(split),