summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorNamilskyy <alive6863@gmail.com>2025-12-28 15:19:04 +0300
committerNamilskyy <alive6863@gmail.com>2025-12-28 15:19:04 +0300
commitbbcbdcbbf95cda5115bbb484b5e2d01669a7a1a0 (patch)
treed57a5ec1044713f2ebbdf694f8b6ecca7f800edf /src/main.rs
parent007ee0bc3534218b2d084f368444d96c16d9d7f9 (diff)
Implementing integrated router funtions and other fuctions
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs454
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
}