aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src/main.rs
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2020-10-16 01:35:59 +0200
committerGustav Sörnäs <gustav@sornas.net>2020-10-16 01:35:59 +0200
commit18a3c0b3cf8254b70857e31ddd2b6213b10db156 (patch)
tree07f7020aaf096b0ed58792ad78527d34f94e4f96 /mumd/src/main.rs
parent8e4eb0afcd0541c6732ebec71af76f3962f590cc (diff)
parentd35c9171271110339504abd96065dc25e1290500 (diff)
downloadmum-18a3c0b3cf8254b70857e31ddd2b6213b10db156.tar.gz
Merge branch 'cli' into 'main'
mumctl See merge request gustav/mum!2
Diffstat (limited to 'mumd/src/main.rs')
-rw-r--r--mumd/src/main.rs118
1 files changed, 27 insertions, 91 deletions
diff --git a/mumd/src/main.rs b/mumd/src/main.rs
index f837a52..14a43c1 100644
--- a/mumd/src/main.rs
+++ b/mumd/src/main.rs
@@ -3,96 +3,41 @@ mod command;
mod network;
mod state;
-use crate::command::{Command, CommandResponse};
use crate::network::ConnectionInfo;
use crate::state::State;
-use argparse::ArgumentParser;
-use argparse::Store;
-use argparse::StoreTrue;
-use colored::*;
use futures::join;
+use ipc_channel::ipc::{IpcSender, IpcOneShotServer};
use log::*;
use mumble_protocol::control::ControlPacket;
use mumble_protocol::crypt::ClientCryptState;
use mumble_protocol::voice::Serverbound;
+use mumlib::command::{Command, CommandResponse};
+use mumlib::setup_logger;
+use std::fs;
use std::sync::{Arc, Mutex};
-use std::time::Duration;
use tokio::sync::{mpsc, watch};
+use tokio::task::spawn_blocking;
#[tokio::main]
async fn main() {
- // setup logger
- fern::Dispatch::new()
- .format(|out, message, record| {
- let message = message.to_string();
- out.finish(format_args!(
- "{} {}:{}{}{}",
- //TODO runtime flag that disables color
- match record.level() {
- Level::Error => "ERROR".red(),
- Level::Warn => "WARN ".yellow(),
- Level::Info => "INFO ".normal(),
- Level::Debug => "DEBUG".green(),
- Level::Trace => "TRACE".normal(),
- },
- record.file().unwrap(),
- record.line().unwrap(),
- if message.chars().any(|e| e == '\n') {
- "\n"
- } else {
- " "
- },
- message
- ))
- })
- .level(log::LevelFilter::Debug)
- .chain(std::io::stderr())
- .apply()
- .unwrap();
-
- // Handle command line arguments
- let mut server_host = "".to_string();
- let mut server_port = 64738u16;
- let mut username = "EchoBot".to_string();
- let mut accept_invalid_cert = false;
- {
- let mut ap = ArgumentParser::new();
- ap.set_description("Run the echo client example");
- ap.refer(&mut server_host)
- .add_option(&["--host"], Store, "Hostname of mumble server")
- .required();
- ap.refer(&mut server_port)
- .add_option(&["--port"], Store, "Port of mumble server");
- ap.refer(&mut username)
- .add_option(&["--username"], Store, "User name used to connect");
- ap.refer(&mut accept_invalid_cert).add_option(
- &["--accept-invalid-cert"],
- StoreTrue,
- "Accept invalid TLS certificates",
- );
- ap.parse_args_or_exit();
- }
+ setup_logger();
// Oneshot channel for setting UDP CryptState from control task
// For simplicity we don't deal with re-syncing, real applications would have to.
let (crypt_state_sender, crypt_state_receiver) = mpsc::channel::<ClientCryptState>(1); // crypt state should always be consumed before sending a new one
let (packet_sender, packet_receiver) = mpsc::unbounded_channel::<ControlPacket<Serverbound>>();
- let (command_sender, command_receiver) = mpsc::unbounded_channel::<Command>();
- let (command_response_sender, command_response_receiver) =
- mpsc::unbounded_channel::<Result<Option<CommandResponse>, ()>>();
+ let (command_sender, command_receiver) = mpsc::unbounded_channel::<(Command, IpcSender<Result<Option<CommandResponse>, ()>>)>();
let (connection_info_sender, connection_info_receiver) =
watch::channel::<Option<ConnectionInfo>>(None);
let state = State::new(
packet_sender,
- command_sender.clone(),
connection_info_sender,
);
let state = Arc::new(Mutex::new(state));
- // Run it
- join!(
+ let (_, _, _, e) = join!(
network::tcp::handle(
Arc::clone(&state),
connection_info_receiver.clone(),
@@ -104,38 +49,29 @@ async fn main() {
connection_info_receiver.clone(),
crypt_state_receiver,
),
- command::handle(state, command_receiver, command_response_sender,),
- send_commands(
- command_sender,
- Command::ServerConnect {
- host: server_host,
- port: server_port,
- username: username.clone(),
- accept_invalid_cert
- }
+ command::handle(
+ state,
+ command_receiver,
),
- receive_command_responses(command_response_receiver,),
+ spawn_blocking(move || { // IpcSender is blocking
+ receive_oneshot_commands(command_sender);
+ }),
);
+ e.unwrap();
}
-async fn send_commands(command_sender: mpsc::UnboundedSender<Command>, connect_command: Command) {
- command_sender.send(connect_command.clone()).unwrap();
- tokio::time::delay_for(Duration::from_secs(2)).await;
- command_sender.send(Command::ServerDisconnect).unwrap();
- tokio::time::delay_for(Duration::from_secs(2)).await;
- command_sender.send(connect_command.clone()).unwrap();
- tokio::time::delay_for(Duration::from_secs(2)).await;
- command_sender.send(Command::ServerDisconnect).unwrap();
-
- debug!("Finished sending commands");
-}
-
-async fn receive_command_responses(
- mut command_response_receiver: mpsc::UnboundedReceiver<Result<Option<CommandResponse>, ()>>,
+fn receive_oneshot_commands(
+ command_sender: mpsc::UnboundedSender<(Command, IpcSender<Result<Option<CommandResponse>, ()>>)>,
) {
- while let Some(command_response) = command_response_receiver.recv().await {
- debug!("{:?}", command_response);
- }
+ loop {
+ // create listener
+ let (server, server_name): (IpcOneShotServer<(Command, IpcSender<Result<Option<CommandResponse>, ()>>)>, String) = IpcOneShotServer::new().unwrap();
+ fs::write("/var/tmp/mumd-oneshot", &server_name).unwrap();
+ debug!("Listening to {}", server_name);
- debug!("Finished receiving commands");
+ // receive command and response channel
+ let (_, conn): (_, (Command, IpcSender<Result<Option<CommandResponse>, ()>>)) = server.accept().unwrap();
+ debug!("Sending to command handler: {:#?}", conn.0);
+ command_sender.send(conn).unwrap();
+ }
}