use clap::Parser; use std::sync::Arc; use std::{env, path::PathBuf, process::exit}; use tetanus::AppState; use tetanus::funcs::*; use tokio::sync::Mutex; mod install; #[derive(Parser, Debug)] #[command( author, version, about = "The Tetanus Redteaming tool. This will start the client, server, or both" )] struct Args { #[arg(short, long, help = "start in client mode")] client: bool, #[arg(short, long, help = "start in server mode")] server: bool, #[arg(short, long, help = "start gui client")] gui: bool, #[arg(short, long, help = "for testing stuff...")] test: bool, } #[tokio::main] async fn main() { let args = Args::parse(); if args.server { let server = Arc::new(Mutex::new(tetanus::server::ServerState { id: 0, running: true, address: String::from("127.0.0.1:31337"), clients: Vec::new(), key: String::new(), })); tetanus::server::start_server(server).await.unwrap(); } else { println!("checking for server or client config files..."); let mut config_path = env::home_dir().unwrap(); config_path.push(".config/tetanus"); if !config_path.exists() { println!("no config directory found in home directory..."); config_path = PathBuf::from("/etc/tetanus"); if !config_path.exists() { println!("no config directory found in /etc/tetanus... Installing!"); let install_result = install::install(); if install_result.is_ok() { install_result.unwrap(); println!("install succeeded!"); exit(0); } } } let args = Args::parse(); let mut client_config_path = config_path.clone(); client_config_path.push("client.conf"); let mut server_config_path = config_path.clone(); server_config_path.push("server.conf"); if args.client { if !client_config_path.exists() { eprintln!( "error: no client config path found at {}", client_config_path.display() ); exit(1); } let (mut appstate, rx) = AppState::new(); let config_load = appstate.load_config(client_config_path.clone()); if config_load.is_err() { eprintln!("error loading config!"); exit(1); } appstate.initialize_modules(); let _res = run_tui(appstate, rx).unwrap(); } } }