Files
tetanus/src/install.rs
T
2026-09-30 09:41:22 -05:00

165 lines
7.3 KiB
Rust

use fs_extra::dir::{CopyOptions, copy};
use std::env;
use std::error::Error;
use std::fs::{File, create_dir_all, remove_dir_all};
use std::io::Write;
use std::path::PathBuf;
use std::process::Command;
use std::process::exit;
use tetanus::funcs::get_user_input;
pub fn install() -> Result<(), Box<dyn Error>> {
let client =
get_user_input("would you like to install the Tetanus on this computer?")?.contains("y");
if client {
client_install()?;
println!(
"
"
)
} else {
println!("Ok then bye... not sure what you wanted here...");
}
return Ok(());
}
pub fn client_install() -> Result<(), Box<dyn Error>> {
if let Some(homedir) = env::home_dir() {
let mut config_path = homedir.clone();
config_path.push(".config/tetanus");
let root_config_folder_path = config_path.clone();
let mut projects_path = config_path.clone();
projects_path.push("projects");
let mut module_path = config_path.clone();
module_path.push("modules");
let mut note_templates_path = config_path.clone();
note_templates_path.push("note_templates");
create_dir_all(&module_path)?;
let current_files_path = PathBuf::from(get_user_input(
"enter the path to store currently in progress project files (not notes), or none if you want to be propted everytime",
)?);
let current_notes_path = PathBuf::from(get_user_input(
"enter the path to store currently in progress project notes, or none if you want to be prompted everytime",
)?);
let upcoming_files_path = PathBuf::from(get_user_input(
"enter the path to store upcoming project files (not notes) or none if you want to be prompted everytime",
)?);
let upcoming_notes_path = PathBuf::from(get_user_input(
"enter the path to store upcoming project notes, or none if you want to be prompted everytime",
)?);
let template_box = get_user_input(
"enter the name of your template distrobox, NONE in all caps if you are not using distrobox",
)?;
println!(
"enter the command used to launch your terminal while running a command. Put the place holder |||COMMAND||| where the command would go"
);
println!(
"if you use a profile to launch the distroboxes, and that profile needs the box name as an environment variable put ENV_NAME= then the name of the variable you use at the end of the command"
);
let term_cmd = get_user_input(
"for example: konsole -e |||COMMAND||| or konsole --profile profile_name ENV_NAME=CURRENT_PROJECT_BOX",
)?;
let tools_folder =
get_user_input("path where your tools are installed ex /opt or /home/user/tools")?;
config_path.push("client.conf");
projects_path.push("default");
create_dir_all(&projects_path)?;
projects_path.push("project.conf");
let mut client_config_file = File::create(&config_path)?;
client_config_file.write(format!("projects: {}\n", projects_path.display()).as_bytes())?;
client_config_file.write("servers: 127.0.0.1:31337\n".as_bytes())?;
let mut default_project_file = File::create(projects_path)?;
config_path.pop();
let mut server_path = config_path.clone();
server_path.push("server");
create_dir_all(&server_path)?;
server_path.push("server.conf");
let mut server_config_file = File::create(&server_path)?;
server_config_file.write("address: 127.0.0.1:31337\n".as_bytes())?;
server_config_file.write("running: false\n".as_bytes())?;
default_project_file.write("org_name: default\n".as_bytes())?;
default_project_file.write("name: default\n".as_bytes())?;
default_project_file
.write(format!("notes: {}\n", current_files_path.display()).as_bytes())?;
default_project_file
.write(format!("files: {}\n", current_notes_path.display()).as_bytes())?;
default_project_file.write("stage: current".as_bytes())?;
client_config_file
.write(format!("current_files: {}\n", current_files_path.display()).as_bytes())?;
client_config_file
.write(format!("current_notes: {}\n", current_notes_path.display()).as_bytes())?;
client_config_file
.write(format!("upcoming_files: {}\n", upcoming_files_path.display()).as_bytes())?;
client_config_file
.write(format!("upcoming_notes: {}\n", upcoming_notes_path.display()).as_bytes())?;
client_config_file.write(format!("module_path: {}\n", module_path.display()).as_bytes())?;
client_config_file.write(format!("template_box: {}\n", template_box).as_bytes())?;
client_config_file.write(format!("term_cmd: {}\n", term_cmd).as_bytes())?;
client_config_file.write(format!("tools: {}\n", tools_folder).as_bytes())?;
client_config_file.write("alternate_configs: \n".as_bytes())?;
println!("\ndefault config files written!");
println!("downloading note templates, victim templates, and modules...");
create_dir_all("./temp")?;
env::set_current_dir("./temp")?;
let git_clone_status = Command::new("git")
.arg("clone")
.arg("https://git.pyro.monster/pyro/tetanus.git")
.status()?
.success();
if git_clone_status {
let mut options = CopyOptions::new();
options.overwrite = true;
options.copy_inside = true;
println!("copying note_templates...");
copy(
"./tetanus/note_templates",
root_config_folder_path.clone(),
&options,
)?;
println!("copying default-modules...");
copy(
"./tetanus/default-modules",
module_path.join("default"),
&options,
)?;
println!("copying default victim templates...");
copy(
"./tetanus/victim_templates",
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")?;
}
} else {
eprintln!("error finding home directory!");
exit(1);
}
return Ok(());
}