diff --git a/src/appstate.rs b/src/appstate.rs index 2e3d635..61a4847 100644 --- a/src/appstate.rs +++ b/src/appstate.rs @@ -32,6 +32,7 @@ use std::sync::{Arc, Mutex, mpsc::Sender, mpsc::channel}; use std::thread; use std::time::Duration; use std::time::{self, Instant}; +use trust_dns_resolver::proto::rr::rdata::svcb::SvcParamKey::Port; use walkdir::WalkDir; pub struct AppState { @@ -282,6 +283,7 @@ impl AppState { "Shortcuts:\nCTRL+P = new_project\nCTRL+s = save\nCTRL_+h = select_host\n".to_string(), ); self.help.push("exclude\nexcludes an IP or a cidr network from the scope and all future tool calls.\nexport 192.168.1.1 192.168.2.0/24\n".to_string()); + self.help.push("start_odysseus\nstarts the odyssues server in the distrobox of the project.\nUSAGE:\nstart_odysseus port_number\n".to_string()); self.help.push("exit\nquit the tool\n".to_string()); self.initialize_modules(); return Ok(()); @@ -1716,6 +1718,50 @@ impl AppState { } } + "start_odysseus" => { + if let Some(args) = command_args { + let working_db = self.projects[self.selected_project].db.clone(); + if let Some(db) = working_db { + if let Some(tools_dir) = self.config.get("TOOLS") { + let mut odysseus_path = None; + let entries = WalkDir::new(tools_dir); + entries.into_iter().for_each(|entry| { + if let Ok(entry) = entry { + if entry.file_name().to_string_lossy().contains("odysseus") { + if entry.path().is_dir() { + odysseus_path = Some(entry.into_path()); + } + } + } + }); + if let Some(path) = odysseus_path { + let tx_clone = self.main_tx.clone(); + self.workers.spawn(move||{ + let output = db.run_command(format!("cd {}; source venv/bin/activate; python -m uvicorn app:app --host 127.0.0.1 --port {}", path.display(), args.trim()).as_str()); + let _ = tx_clone.send(ToolMessage::Output((rid, format!("{}", output)))); + }); + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + "[success] odysseus command ran!".to_string(), + ))); + } + } + } + } else { + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + "[error] malformed command".to_string(), + ))); + let _ = self + .main_tx + .send(ToolMessage::Output((rid, "[error] USAGE:".to_string()))); + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + "[error] start_odysseus {port number}".to_string(), + ))); + } + } + "exit" => { self.save_all()?; let _ = self.main_tx.send(ToolMessage::AppStateExit); diff --git a/src/install.rs b/src/install.rs index 75e2998..43ddfe3 100644 --- a/src/install.rs +++ b/src/install.rs @@ -129,6 +129,30 @@ pub fn client_install() -> Result<(), Box> { root_config_folder_path.join("victim"), &options, )?; + if get_user_input( + "do you want to copy tetanus to your path so you can run it anywhere?", + )? + .contains("y") + { + println!("this will require sudo. Please complete the following sudo prompt."); + if let Ok(exe_path) = env::current_exe() { + if let Ok(res) = Command::new("sudo") + .arg("cp") + .arg(exe_path.display().to_string()) + .arg("/usr/bin/tetanus") + .status() + { + if res.success() { + println!("copied to path!"); + println!("install completed!"); + } else { + eprintln!( + "error copying to path. please copy this executable to your path manually." + ); + } + } + } + } env::set_current_dir("../")?; remove_dir_all("./temp")?; } diff --git a/src/project.rs b/src/project.rs index d193517..d11917d 100644 --- a/src/project.rs +++ b/src/project.rs @@ -318,7 +318,7 @@ impl DistroBox { if !added_volumes.contains(&String::from(folder_name)) { create_command .arg("--volume") - .arg(format!("{}:/{}:rw", volume, folder_name)); + .arg(format!("{}:/project:rw", volume)); added_volumes.push(folder_name.to_string()); } }