1use std::sync::atomic::Ordering;
2use std::{io::Write, sync::atomic::AtomicUsize};
3
4mod config;
5mod fronts;
6
7mod socks2http;
8
9use colored::Colorize;
10
11use pad::{Alignment, PadStr};
12
13use smol::channel::Sender;
14use structopt::StructOpt;
15
16use crate::{config::Opt, connect::ConnectDaemon, debugpack::DebugPack};
17mod binderproxy;
18mod china;
19mod connect;
20
21mod debugpack;
22mod main_bridgetest;
23
24mod sync;
25
26pub fn dispatch() -> anyhow::Result<()> {
30 std::env::remove_var("http_proxy");
31 std::env::remove_var("https_proxy");
32
33 let (send_logs, recv_logs) = smol::channel::bounded(1000);
34 config_logging(send_logs);
35 let version = env!("CARGO_PKG_VERSION");
36 log::info!("geph4-client v{} starting...", version);
37 std::env::set_var("GEPH_VERSION", version);
38
39 let opt = Opt::from_args();
40 smolscale::block_on(async move {
41 match opt {
42 Opt::Connect(opt) => {
43 let daemon = ConnectDaemon::start(opt).await?;
44 loop {
45 let log = recv_logs.recv().await?;
46 daemon.debug().add_logline(&log);
47 }
48 }
49 Opt::Sync(opt) => sync::main_sync(opt.clone()).await,
50 Opt::BinderProxy(opt) => binderproxy::main_binderproxy(opt.clone()).await,
51 Opt::BridgeTest(opt) => main_bridgetest::main_bridgetest(opt.clone()).await,
52 Opt::DebugPack(opt) => {
53 let pack = DebugPack::new(&opt.common.debugpack_path)?;
54 pack.backup(&opt.export_to)?;
55 Ok(())
56 }
57 }
58 })
59}
60
61static LONGEST_LINE_EVER: AtomicUsize = AtomicUsize::new(0);
62
63fn config_logging(logs: Sender<String>) {
64 if let Err(e) =
65 env_logger::Builder::from_env(env_logger::Env::default().default_filter_or(
66 "geph4client=debug,geph4_protocol=debug,melprot=debug,warn,geph5=debug",
67 ))
68 .format_timestamp_millis()
69 .format(move |buf, record| {
70 let preamble = format!(
71 "[{} {}]:",
72 record.module_path().unwrap_or("none").dimmed(),
73 match record.level() {
74 log::Level::Error => "ERRO".red(),
75 log::Level::Warn => "WARN".bright_yellow(),
76 log::Level::Info => "INFO".bright_green(),
77 log::Level::Debug => "DEBG".bright_blue(),
78 log::Level::Trace => "TRAC".bright_black(),
79 },
80 );
81 let len = strip_ansi_escapes::strip(&preamble).unwrap().len();
82 let longest = LONGEST_LINE_EVER.fetch_max(len, Ordering::SeqCst);
83 let preamble = ""
84 .pad_to_width_with_alignment(longest.saturating_sub(len), Alignment::Right)
85 + &preamble;
86 let line = format!("{} {}", preamble, record.args());
87 writeln!(buf, "{}", line).unwrap();
88 let _ = logs.try_send(
89 String::from_utf8_lossy(&strip_ansi_escapes::strip(line).unwrap()).to_string(),
90 );
91 Ok(())
92 })
93 .format_target(false)
94 .try_init()
95 {
96 log::debug!("{}", e);
97 }
98}