use clap::{Parser, Subcommand};
#[derive(Parser, Debug)]
#[command(name = "gout", version, about = "轻量内网穿透工具")]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
}
#[derive(Subcommand, Debug)]
pub enum Command {
Login {
server: String,
key: String,
},
Tcp {
port: u16,
#[arg(long, short = 'd')]
detach: bool,
},
Udp {
port: u16,
#[arg(long, short = 'd')]
detach: bool,
},
Http {
port: u16,
#[arg(long, short = 'd')]
detach: bool,
},
List,
Log {
port: u16,
#[arg(long, short = 'f')]
follow: bool,
},
Kill {
port: u16,
},
}
impl Cli {
pub fn run() -> anyhow::Result<()> {
let cli = Cli::parse();
if let Some(pidfile) = std::env::var("GOUT_DAEMON_PIDFILE").ok() {
let result = match cli.command {
Command::Tcp { port, .. } => crate::cmd_tunnel("tcp", port),
Command::Udp { port, .. } => crate::cmd_tunnel("udp", port),
Command::Http { port, .. } => crate::cmd_tunnel("http", port),
_ => anyhow::bail!("daemon mode unsupported for this command"),
};
std::fs::remove_file(&pidfile).ok();
return result;
}
match cli.command {
Command::Login { server, key } => crate::cmd_login(&server, &key),
Command::Tcp { port, detach: true } => crate::cmd_start_daemon("tcp", port),
Command::Tcp { port, detach: false } => crate::cmd_tunnel("tcp", port),
Command::Udp { port, detach: true } => crate::cmd_start_daemon("udp", port),
Command::Udp { port, detach: false } => crate::cmd_tunnel("udp", port),
Command::Http { port, detach: true } => crate::cmd_start_daemon("http", port),
Command::Http { port, detach: false } => crate::cmd_tunnel("http", port),
Command::Log { port, follow } => crate::cmd_log(port, follow),
Command::Kill { port } => crate::cmd_kill(port),
Command::List => crate::cmd_list(),
}
}
}