diff options
| author | Namilskyy <alive6863@gmail.com> | 2025-12-28 15:19:04 +0300 |
|---|---|---|
| committer | Namilskyy <alive6863@gmail.com> | 2025-12-28 15:19:04 +0300 |
| commit | bbcbdcbbf95cda5115bbb484b5e2d01669a7a1a0 (patch) | |
| tree | d57a5ec1044713f2ebbdf694f8b6ecca7f800edf /src/main.rs | |
| parent | 007ee0bc3534218b2d084f368444d96c16d9d7f9 (diff) | |
Implementing integrated router funtions and other fuctions
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 454 |
1 files changed, 275 insertions, 179 deletions
diff --git a/src/main.rs b/src/main.rs index bbd4187..4e1402d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,22 +2,64 @@ mod cfg; mod net; mod openpgp; mod pkgtoolkit; -mod router; +mod router; use crate::cfg::config::Config; use crate::net::{http_package::HTTPPackage, i2p_package::I2PPackage}; -use crate::openpgp::trusted; use crate::pkgtoolkit::Package; use crate::pkgtoolkit::archive::ArchiveOperations; use crate::pkgtoolkit::build::BuildOperations; use crate::pkgtoolkit::git_source::GitSource; use crate::pkgtoolkit::index::IndexOperations; use crate::pkgtoolkit::install::InstallOperations; +use crate::router::router::{Emissary, EmissaryConfig, RouterUtils}; +use emissary_core::router::Router; +use emissary_util::runtime::tokio::Runtime as TokioRuntime; +use std::sync::Arc; +use tokio::sync::Mutex; use clap::{Args, Parser, Subcommand}; use std::io::Write; use std::path::Path; +lazy_static::lazy_static! { + static ref ROUTER: Arc<Mutex<Option<Router<TokioRuntime>>>> = Arc::new(Mutex::new(None)); +} + +async fn init_router( + config: &crate::cfg::config::Config, +) -> Result<(), Box<dyn std::error::Error>> { + if !config.router.integrated_router { + return Ok(()); + } + + let router_config = EmissaryConfig { + storage: Some(std::path::PathBuf::from(&config.router.storage_path)), + auto_update: Some(config.router.auto_update), + http_proxy_port: Some(config.router.http_proxy_port), + socks_proxy_port: Some(config.router.socks_proxy_port), + }; + + let mut router = Emissary::new(router_config); + + // Check if router storage exists and is not empty + let storage_path = std::path::Path::new(&config.router.storage_path); + if !storage_path.exists() || storage_path.read_dir()?.next().is_none() { + log::info!("Router storage is empty, performing initial reseed..."); + router.config().await?; + router.reseed().await?; + } else { + router.config().await?; + } + + // Start the router and store the Router instance + let router = router.start().await?; + *ROUTER.lock().await = Some(router); + + log::info!("Integrated router initialized successfully"); + Ok(()) +} + #[derive(Parser)] struct Cli { #[command(subcommand)] @@ -80,97 +122,50 @@ struct RemoteInstallArgs { #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { - let cli: Cli = Cli::parse(); - - match &cli.command { - Commands::Validate { path } => { - println!("Validating {}", path); - match Package::check(path.to_string()) { - Ok(is_valid) => { - if is_valid { - println!("Package archive is valid."); - } else { - println!("Package archive is invalid."); - return Err(std::io::Error::other("Invalid package archive").into()); - } - } - Err(e) => { - log::error!("Failed to validate package '{}': {}", path, e); - return Err(e.into()); - } - } - return Ok(()); - } - Commands::Build { pkgname } => { - println!("Building package from archive: {}", pkgname); - - let path = Path::new(&pkgname); - if !path.exists() { - return Err(std::io::Error::other(format!( - "Package archive not found: {}", - pkgname - )) - .into()); - } + let config = crate::cfg::config::Config::parse()?; - if !path.is_file() { - return Err( - std::io::Error::other(format!("Path is not a file: {}", pkgname)).into(), - ); - } + init_router(&config).await?; + let cli: Cli = Cli::parse(); - println!("Extracting archive..."); - Package::extract_archive(pkgname)?; - - let config = Config::parse().unwrap(); - let cache_dir = &config.paths.cache_dir; - - // Find the package directory (should be name-version format) - let mut pkg_dir_name = None; - for entry in std::fs::read_dir(cache_dir)? { - let entry = entry?; - let path = entry.path(); - if path.is_dir() { - let dir_name = path.file_name().unwrap().to_string_lossy(); - if dir_name.contains('-') && dir_name != "temp_extract" { - let install_path = path.join("INSTALL"); - if install_path.exists() { - pkg_dir_name = Some(dir_name.to_string()); - break; + let config = Arc::new(config); + + let result = { + match &cli.command { + Commands::Validate { path } => { + println!("Validating {}", path); + match Package::check(path.to_string()) { + Ok(is_valid) => { + if is_valid { + println!("Package archive is valid."); + } else { + println!("Package archive is invalid."); + return Err(std::io::Error::other("Invalid package archive").into()); } } + Err(e) => { + log::error!("Failed to validate package '{}': {}", path, e); + return Err(e.into()); + } } + return Ok(()); } + Commands::Build { pkgname } => { + println!("Building package from archive: {}", pkgname); + + let path = Path::new(&pkgname); + if !path.exists() { + return Err(std::io::Error::other(format!( + "Package archive not found: {}", + pkgname + )) + .into()); + } - let pkg_dir_name = pkg_dir_name - .ok_or_else(|| std::io::Error::other("Package directory not found in cache"))?; - - let install_toml_path = Path::new(cache_dir).join(format!("{}/INSTALL", pkg_dir_name)); - - if !install_toml_path.exists() { - return Err( - std::io::Error::other("INSTALL file not found in package directory").into(), - ); - } - - let install_content = std::fs::read_to_string(&install_toml_path)?; - let install_data: crate::pkgtoolkit::types::Install = toml::from_str(&install_content)?; - - let mut pkg = install_data.package; - - println!("Building package '{}'...", pkg.name); - pkg.build()?; - println!("Package '{}' built successfully.", pkg.name); - return Ok(()); - } - Commands::Install { - pkgname, - source: _, - path, - args, - } => { - if *path { - println!("Installing package from local file: {}", pkgname); + if !path.is_file() { + return Err( + std::io::Error::other(format!("Path is not a file: {}", pkgname)).into(), + ); + } println!("Extracting archive..."); Package::extract_archive(pkgname)?; @@ -178,6 +173,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { let config = Config::parse().unwrap(); let cache_dir = &config.paths.cache_dir; + // Find the package directory (should be name-version format) let mut pkg_dir_name = None; for entry in std::fs::read_dir(cache_dir)? { let entry = entry?; @@ -199,6 +195,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { let install_toml_path = Path::new(cache_dir).join(format!("{}/INSTALL", pkg_dir_name)); + + if !install_toml_path.exists() { + return Err(std::io::Error::other( + "INSTALL file not found in package directory", + ) + .into()); + } + let install_content = std::fs::read_to_string(&install_toml_path)?; let install_data: crate::pkgtoolkit::types::Install = toml::from_str(&install_content)?; @@ -207,107 +211,199 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { println!("Building package '{}'...", pkg.name); pkg.build()?; + println!("Package '{}' built successfully.", pkg.name); + return Ok(()); + } + Commands::Install { + pkgname, + source: _, + path, + args, + } => { + if *path { + println!("Installing package from local file: {}", pkgname); + + println!("Extracting archive..."); + Package::extract_archive(pkgname)?; + + let config = Config::parse().unwrap(); + let cache_dir = &config.paths.cache_dir; + + let mut pkg_dir_name = None; + for entry in std::fs::read_dir(cache_dir)? { + let entry = entry?; + let path = entry.path(); + if path.is_dir() { + let dir_name = path.file_name().unwrap().to_string_lossy(); + if dir_name.contains('-') && dir_name != "temp_extract" { + let install_path = path.join("INSTALL"); + if install_path.exists() { + pkg_dir_name = Some(dir_name.to_string()); + break; + } + } + } + } + + let pkg_dir_name = pkg_dir_name.ok_or_else(|| { + std::io::Error::other("Package directory not found in cache") + })?; + + let install_toml_path = + Path::new(cache_dir).join(format!("{}/INSTALL", pkg_dir_name)); + let install_content = std::fs::read_to_string(&install_toml_path)?; + let install_data: crate::pkgtoolkit::types::Install = + toml::from_str(&install_content)?; - println!("Installing package '{}'...", pkg.name); - pkg.install()?; - println!("Package '{}' installed successfully.", pkg.name); - } else { + let mut pkg = install_data.package; + + println!("Building package '{}'...", pkg.name); + pkg.build()?; + + println!("Installing package '{}'...", pkg.name); + pkg.install()?; + println!("Package '{}' installed successfully.", pkg.name); + } else { + let config = Config::parse().unwrap(); + if args.http { + println!("Installing {} via HTTP", pkgname); + let mut http_client = HTTPPackage::new(config); + http_client.fetch_index_http().await?; + log::info!("Index fetched successfully."); + http_client.fetch_package_http(pkgname).await?; + log::info!("Package '{}' installed successfully.", pkgname); + } else { + println!("Installing {} via I2P", pkgname); + let mut i2p_client = I2PPackage::new(config); + i2p_client.fetch_index().await?; + log::info!("Index fetched successfully."); + i2p_client.fetch_package(pkgname).await?; + log::info!("Package '{}' installed successfully.", pkgname); + } + } + return Ok(()); + } + Commands::Uninstall { pkgname } => { + println!("Uninstalling package: {}", pkgname); + + let installed_packages = Package::list_installed_packages().map_err(|e| { + log::error!("Failed to list installed packages: {}", e); + e + })?; + + let package_manifest = installed_packages + .iter() + .find(|p| p.name == *pkgname) + .ok_or_else(|| { + std::io::Error::other(format!("Package '{}' is not installed", pkgname)) + })?; + + let package = Package { + name: package_manifest.name.clone(), + version: package_manifest.version.clone(), + ..Default::default() + }; + + match package.uninstall() { + Ok(true) => { + println!("Successfully uninstalled package: {}", pkgname); + Ok(()) + } + Ok(false) => { + log::warn!( + "Some files could not be removed during uninstallation of {}", + pkgname + ); + Err(std::io::Error::other("Partial uninstallation occurred").into()) + } + Err(e) => { + log::error!("Failed to uninstall package {}: {}", pkgname, e); + Err(e.into()) + } + } + } + Commands::GetSource { pkgname } => { let config = Config::parse().unwrap(); - if args.http { - println!("Installing {} via HTTP", pkgname); - let mut http_client = HTTPPackage::new(config); - http_client.fetch_index_http().await?; - log::info!("Index fetched successfully."); - http_client.fetch_package_http(pkgname).await?; - log::info!("Package '{}' installed successfully.", pkgname); + println!("Getting source of {}", pkgname); + + let source_path = GitSource::get_source_by_name(pkgname, &config)?; + println!("Source code successfully downloaded to: {}", source_path); + return Ok(()); + } + Commands::DefaultConfig { + repo, + cachedir, + buildir, + installed_db, + } => { + println!("Generating config file"); + if cachedir.is_none() && repo.is_none() && buildir.is_none() { + let config = Config::default().unwrap(); + + println!("---- Start of generated config ----"); + println!("{}", config); + println!("---- End of generated config ----"); + + log::warn!("Writing the default config to /etc/mesk/mesk.toml"); + + let path = Path::new("/etc/mesk/mesk.toml"); + std::fs::create_dir_all(path.parent().unwrap())?; + let mut file = std::fs::File::create(path)?; + file.write_all(config.as_bytes())?; + println!("Config tool ending work."); } else { - println!("Installing {} via I2P", pkgname); - let mut i2p_client = I2PPackage::new(config); - i2p_client.fetch_index().await?; - log::info!("Index fetched successfully."); - i2p_client.fetch_package(pkgname).await?; - log::info!("Package '{}' installed successfully.", pkgname); + let config = Config::generate(repo, cachedir, buildir, installed_db).unwrap(); + + println!("---- Start of generated config ----"); + println!("{:?}", config); + println!("---- End of generated config ----"); + + log::warn!("Writing the default config to /etc/mesk/mesk.toml"); + + let path = Path::new("/etc/mesk/mesk.toml"); + std::fs::create_dir_all(path.parent().unwrap())?; + let mut file = std::fs::File::create(path)?; + file.write_all(config.as_bytes())?; + println!("Config tool ending work."); } + return Ok(()); } - return Ok(()); - } - Commands::Uninstall { pkgname } => { - println!("Uninstalling {}", pkgname); - return Ok(()); - } - Commands::GetSource { pkgname } => { - let config = Config::parse().unwrap(); - println!("Getting source of {}", pkgname); + Commands::Update => { + let config = Config::parse().unwrap(); + println!("Updating index from {}", config.repo.repo_url); - let source_path = GitSource::get_source_by_name(pkgname, &config)?; - println!("Source code successfully downloaded to: {}", source_path); - return Ok(()); - } - Commands::DefaultConfig { - repo, - cachedir, - buildir, - installed_db, - } => { - println!("Generating config file"); - if cachedir.is_none() && repo.is_none() && buildir.is_none() { - let config = Config::default().unwrap(); - - println!("---- Start of generated config ----"); - println!("{}", config); - println!("---- End of generated config ----"); - - log::warn!("Writing the default config to /etc/mesk/mesk.toml"); - - let path = Path::new("/etc/mesk/mesk.toml"); - std::fs::create_dir_all(path.parent().unwrap())?; - let mut file = std::fs::File::create(path)?; - file.write_all(config.as_bytes())?; - println!("Config tool ending work."); - } else { - let config = Config::generate(repo, cachedir, buildir, installed_db).unwrap(); - - println!("---- Start of generated config ----"); - println!("{:?}", config); - println!("---- End of generated config ----"); - - log::warn!("Writing the default config to /etc/mesk/mesk.toml"); - - let path = Path::new("/etc/mesk/mesk.toml"); - std::fs::create_dir_all(path.parent().unwrap())?; - let mut file = std::fs::File::create(path)?; - file.write_all(config.as_bytes())?; - println!("Config tool ending work."); + let mut i2p_client = I2PPackage::new(config); + i2p_client.fetch_index().await?; + println!("Index updated successfully."); + return Ok(()); } - return Ok(()); - } - Commands::Update => { - let config = Config::parse().unwrap(); - println!("Updating index from {}", config.repo.repo_url); - - let mut i2p_client = I2PPackage::new(config); - i2p_client.fetch_index().await?; - println!("Index updated successfully."); - return Ok(()); - } - Commands::Upgrade { pkgname } => { - println!("Upgrading {}", pkgname.as_deref().unwrap_or("all packages")); - return Ok(()); - } - Commands::Credits => { - println!( - "CREATED BY: Asya and Namilsk as part of the Anthrill independent Global network distribution project" - ); - println!(" "); - println!("The Anthrill project repos: https://codeberg.org/NamelessTeam "); - return Ok(()); - } - Commands::GenIndex { path } => { - println!("Generating index for {}", path); + Commands::Upgrade { pkgname } => { + println!("Upgrading {}", pkgname.as_deref().unwrap_or("all packages")); + return Ok(()); + } + Commands::Credits => { + println!( + "CREATED BY: Namilsk as part of the Anthrill independent Global network distribution project" + ); + println!(" "); + println!("The Anthrill project repos: https://codeberg.org/NamelessTeam "); + return Ok(()); + } + Commands::GenIndex { path } => { + println!("Generating index for {}", path); - Package::gen_index(path)?; - println!("Index generated successfully."); - return Ok(()); + Package::gen_index(path)?; + println!("Index generated successfully."); + return Ok(()); + } } + }; + + // Shutdown router if it was initialized + if let Some(router) = ROUTER.lock().await.take() { + // TODO: Add proper router shutdown when implemented + log::info!("Shutting down integrated router..."); } + + result } |
