Files
Core/process/src/p2prc.rs
2025-06-28 12:41:53 +01:00

192 lines
5.4 KiB
Rust

use std::fs;
use std::io::Error;
use std::net::IpAddr;
use std::process::{Command, Output};
use serde::{Deserialize, Serialize};
use serde::de::DeserializeOwned;
#[derive(Debug, Serialize, Deserialize)]
pub struct IPAddressList {
pub ip_address: Vec<IPAddressEntry>,
}
// Maps p2prc --ls output to the following
// data structure
#[derive(Debug, Serialize, Deserialize)]
pub struct IPAddressEntry {
pub Name: String,
pub MachineUsername: String,
pub IPV4: String,
pub IPV6: String,
pub Latency: u64,
pub Download: u64,
pub Upload: u64,
pub ServerPort: String,
pub BareMetalSSHPort: String,
pub NAT: bool,
pub EscapeImplementation: String,
pub ProxyServer: bool,
pub UnSafeMode: bool,
pub PublicKey: String,
pub CustomInformation: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Config {
#[serde(rename = "MachineName")]
pub machine_name: String,
#[serde(rename = "IPTable")]
pub iptable: String,
#[serde(rename = "DockerContainers")]
pub docker_containers: String,
#[serde(rename = "DefaultDockerFile")]
pub default_docker_file: String,
#[serde(rename = "DockerRunLogs")]
pub docker_run_logs: String,
#[serde(rename = "SpeedTestFile")]
pub speed_test_file: String,
#[serde(rename = "IPV6Address")]
pub ipv6address: String,
#[serde(rename = "PluginPath")]
pub plugin_path: String,
#[serde(rename = "TrackContainersPath")]
pub track_containers_path: String,
#[serde(rename = "ServerPort")]
pub server_port: String,
#[serde(rename = "ProxyPort")]
pub proxy_port: String,
#[serde(rename = "GroupTrackContainersPath")]
pub group_track_containers_path: String,
#[serde(rename = "FRPServerPort")]
pub frpserver_port: bool,
#[serde(rename = "BehindNAT")]
pub behind_nat: bool,
#[serde(rename = "IPTableKey")]
pub iptable_key: String,
#[serde(rename = "PublicKeyFile")]
pub public_key_file: String,
#[serde(rename = "PrivateKeyFile")]
pub private_key_file: String,
#[serde(rename = "PemFile")]
pub pem_file: String,
#[serde(rename = "KeyFile")]
pub key_file: String,
#[serde(rename = "BareMetal")]
pub bare_metal: bool,
#[serde(rename = "UnsafeMode")]
pub unsafe_mode: bool,
#[serde(rename = "Test")]
pub test: bool,
#[serde(rename = "ConfigPath")]
pub config_path: String
}
#[derive(Serialize, Deserialize, Debug)]
pub struct MapPort {
#[serde(rename = "IPAddress")]
pub ipaddress: String,
#[serde(rename = "PortNo")]
pub port_no: String,
#[serde(rename = "EntireAddress")]
pub entire_address: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Specs {
#[serde(rename = "Hostname")]
pub hostname: String,
#[serde(rename = "Platform")]
pub platform: String,
#[serde(rename = "CPU")]
pub cpu: String,
#[serde(rename = "RAM")]
pub ram: i64,
#[serde(rename = "Disk")]
pub disk: i64,
}
// Runs p2prc with custom arguments called.
// Function implemented as an identity function
pub fn run_p2prc_command<T>(arguments: &str) -> T
where
T: DeserializeOwned,
{
let command_str = format!("p2prc {}", arguments);
let output = Command::new("sh")
.arg("-c")
.arg(&command_str)
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
serde_json::from_str(&stdout).expect("Failed to deserialize JSON output")
}
// Runs p2prc map port command
pub fn p2prc_map_port_command(local_port_no: &str, domain_name: &str,remote_server: &str) -> MapPort{
// Needs a reviews for a better representation
let mut command = vec!["".to_string()];
match !local_port_no.is_empty() {
true => command.push(format!("--mp {}", local_port_no)),
false => (),
}
match !domain_name.is_empty() {
true => command.push(format!("--dn {}", domain_name)),
false => (),
}
match !remote_server.is_empty() {
true => command.push(format!("--ra {}", remote_server)),
false => (),
}
let command = command.join(" ");
println!("{:#?}", command);
let map_port: MapPort = run_p2prc_command(&*command);
map_port
}
// Runs p2prc list server command
pub fn p2prc_list_server_command() -> IPAddressList {
let servers: IPAddressList = run_p2prc_command(&*"--ls".to_string());
servers
}
// Starts p2prc server in the background
pub async fn p2prc_start_server() {
let run_server: Option<bool> = run_p2prc_command(&*"-s".to_string());
}
// Read P2PRC config file
pub fn p2prc_read_config() -> Config {
let config: Config = run_p2prc_command(&*"--vc".to_string());
config
}
// Writes changes to the config file
// write to the config path provided in the config type
// unoptimised but reduces code complexity
pub fn p2prc_write_config(config: Config) {
// Convert config type to a string
let json:String = serde_json::to_string(&config).unwrap().to_string();
fs::write(config.config_path, json).expect("Panic message: ");
}
// Set default config (--dc command)
pub fn p2prc_default_config() {
let _: Option<bool> = run_p2prc_command(&*"--dc".to_string());
}
// Get hardware information of a remote server
pub fn p2prc_get_specs(ip_addr: String) -> Specs {
let command: String = format!("--specs {}", ip_addr);
let specs: Specs = run_p2prc_command(&*command);
specs
}