Refactor in prep for clip
This commit is contained in:
parent
3f7afc5b78
commit
3eba65f6e6
8 changed files with 101 additions and 94 deletions
|
|
@ -22,7 +22,7 @@ indoc = "1"
|
|||
log = { version = "0.4", features = ["std"] }
|
||||
open = "3"
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["io-std", "io-util", "macros", "net", "process", "rt", "rt-multi-thread"] }
|
||||
tokio = { version = "1", features = ["io-std", "io-util", "macros", "net", "process", "rt", "rt-multi-thread", "fs"] }
|
||||
tokio-stream = "0.1"
|
||||
toml = "0.5"
|
||||
tui = "0.19"
|
||||
|
|
|
|||
|
|
@ -9,5 +9,10 @@ async fn main() {
|
|||
std::process::exit(1);
|
||||
}
|
||||
|
||||
fwd::browse_url(&args[1]).await;
|
||||
let url = &args[1];
|
||||
if let Err(e) = fwd::browse_url(url).await {
|
||||
eprintln!("Unable to open {url}");
|
||||
eprintln!("{}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
use crate::message::Message;
|
||||
use anyhow::Result;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
mod browse_unix;
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
use browse_unix::{browse_url_impl, handle_browser_open_impl};
|
||||
|
||||
#[inline]
|
||||
pub async fn browse_url(url: &String) {
|
||||
if let Err(e) = browse_url_impl(url).await {
|
||||
eprintln!("Unable to open {url}");
|
||||
eprintln!("{}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_family = "unix"))]
|
||||
pub async fn browse_url_impl(_url: &String) -> Result<()> {
|
||||
use anyhow::anyhow;
|
||||
Err(anyhow!(
|
||||
"Opening a browser is not supported on this platform"
|
||||
))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn handle_browser_open(
|
||||
messages: mpsc::Sender<Message>,
|
||||
) -> Result<()> {
|
||||
handle_browser_open_impl(messages).await
|
||||
}
|
||||
|
||||
#[cfg(not(target_family = "unix"))]
|
||||
async fn handle_browser_open_impl(
|
||||
_messages: mpsc::Sender<Message>,
|
||||
) -> Result<()> {
|
||||
std::future::pending().await
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
mod browse;
|
||||
mod client;
|
||||
mod message;
|
||||
mod reverse;
|
||||
mod server;
|
||||
|
||||
pub use browse::browse_url;
|
||||
pub use client::run_client;
|
||||
pub use reverse::browse_url;
|
||||
pub use server::run_server;
|
||||
|
|
|
|||
22
src/main.rs
22
src/main.rs
|
|
@ -5,7 +5,7 @@ const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|||
|
||||
fn usage() {
|
||||
println!(indoc! {"
|
||||
usage: fwd [options] (<server> | browse <url>)
|
||||
usage: fwd [options] (<server> | browse <url> | clip [<file>])
|
||||
|
||||
To connect a client to a server that has an `fwd` installed in its path, run
|
||||
`fwd <server>` on the client, where <server> is the name of the server to
|
||||
|
|
@ -60,9 +60,13 @@ fn parse_args(args: Vec<String>) -> Args {
|
|||
} else {
|
||||
Args::Error
|
||||
}
|
||||
} else if rest.len() > 1 && rest[0] == "browse" {
|
||||
if rest.len() == 2 {
|
||||
Args::Browse(rest[1].to_string())
|
||||
} else if rest.len() > 1 {
|
||||
if rest[0] == "browse" {
|
||||
if rest.len() == 2 {
|
||||
Args::Browse(rest[1].to_string())
|
||||
} else {
|
||||
Args::Error
|
||||
}
|
||||
} else {
|
||||
Args::Error
|
||||
}
|
||||
|
|
@ -73,6 +77,14 @@ fn parse_args(args: Vec<String>) -> Args {
|
|||
}
|
||||
}
|
||||
|
||||
async fn browse_url(url: &str) {
|
||||
if let Err(e) = fwd::browse_url(&url).await {
|
||||
eprintln!("Unable to open {url}");
|
||||
eprintln!("{}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
match parse_args(std::env::args().collect()) {
|
||||
|
|
@ -86,7 +98,7 @@ async fn main() {
|
|||
fwd::run_server().await;
|
||||
}
|
||||
Args::Browse(url) => {
|
||||
fwd::browse_url(&url).await;
|
||||
browse_url(&url).await;
|
||||
}
|
||||
Args::Client(server, sudo) => {
|
||||
fwd::run_client(&server, sudo).await;
|
||||
|
|
|
|||
29
src/reverse.rs
Normal file
29
src/reverse.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
use anyhow::Result;
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
mod unix;
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
pub use unix::{handle_reverse_connections, send_reverse_message};
|
||||
|
||||
use crate::message::Message;
|
||||
|
||||
#[cfg(not(target_family = "unix"))]
|
||||
pub async fn send_reverse_message(_message: Message) -> Result<()> {
|
||||
use anyhow::anyhow;
|
||||
Err(anyhow!(
|
||||
"Server-side operations are not supported on this platform"
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(not(target_family = "unix"))]
|
||||
pub async fn handle_reverse_connections(
|
||||
_messages: mpsc::Sender<Message>,
|
||||
) -> Result<()> {
|
||||
std::future::pending().await
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn browse_url(url: &str) -> Result<()> {
|
||||
send_reverse_message(Message::Browse(url.to_string())).await
|
||||
}
|
||||
|
|
@ -1,14 +1,15 @@
|
|||
use crate::message::{Message, MessageReader, MessageWriter};
|
||||
// The reverse client connects to the server via a local connection to send
|
||||
// commands back to the client.
|
||||
use anyhow::{bail, Context, Result};
|
||||
use log::warn;
|
||||
use std::os::unix::fs::DirBuilderExt;
|
||||
use std::path::PathBuf;
|
||||
use tokio::net::{UnixListener, UnixStream};
|
||||
use tokio::sync::mpsc;
|
||||
use users;
|
||||
use xdg;
|
||||
|
||||
pub async fn browse_url_impl(url: &String) -> Result<()> {
|
||||
use crate::message::{Message, MessageReader, MessageWriter};
|
||||
|
||||
pub async fn send_reverse_message(message: Message) -> Result<()> {
|
||||
let path = socket_path().context("Error getting socket path")?;
|
||||
let stream = match UnixStream::connect(&path).await {
|
||||
Ok(s) => s,
|
||||
|
|
@ -18,38 +19,22 @@ pub async fn browse_url_impl(url: &String) -> Result<()> {
|
|||
};
|
||||
let mut writer = MessageWriter::new(stream);
|
||||
writer
|
||||
.write(Message::Browse(url.clone()))
|
||||
.write(message)
|
||||
.await
|
||||
.context("Error sending browse message")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn handle_browser_open_impl(
|
||||
messages: mpsc::Sender<Message>,
|
||||
) -> Result<()> {
|
||||
let path = socket_path().context("Error getting socket path")?;
|
||||
handle_browser_open_with_path(messages, path).await
|
||||
}
|
||||
|
||||
async fn handle_browser_open_with_path(
|
||||
messages: mpsc::Sender<Message>,
|
||||
path: PathBuf,
|
||||
) -> Result<()> {
|
||||
let _ = std::fs::remove_file(&path);
|
||||
let listener = UnixListener::bind(&path)
|
||||
.with_context(|| format!("Failed to bind to {}", path.display()))?;
|
||||
loop {
|
||||
let (socket, _addr) = listener
|
||||
.accept()
|
||||
.await
|
||||
.context("Error accepting connection")?;
|
||||
|
||||
let sender = messages.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = handle_connection(socket, sender).await {
|
||||
warn!("Error handling socket connection: {:?}", e);
|
||||
}
|
||||
});
|
||||
fn socket_directory() -> Result<std::path::PathBuf> {
|
||||
let base_directories = xdg::BaseDirectories::new()
|
||||
.context("Error creating BaseDirectories")?;
|
||||
match base_directories.place_runtime_file("fwd") {
|
||||
Ok(path) => Ok(path),
|
||||
Err(_) => {
|
||||
let mut path = std::env::temp_dir();
|
||||
path.push(format!("fwd{}", users::get_current_uid()));
|
||||
Ok(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -68,16 +53,32 @@ pub fn socket_path() -> Result<PathBuf> {
|
|||
Ok(socket_path)
|
||||
}
|
||||
|
||||
fn socket_directory() -> Result<std::path::PathBuf> {
|
||||
let base_directories = xdg::BaseDirectories::new()
|
||||
.context("Error creating BaseDirectories")?;
|
||||
match base_directories.place_runtime_file("fwd") {
|
||||
Ok(path) => Ok(path),
|
||||
Err(_) => {
|
||||
let mut path = std::env::temp_dir();
|
||||
path.push(format!("fwd{}", users::get_current_uid()));
|
||||
Ok(path)
|
||||
}
|
||||
pub async fn handle_reverse_connections(
|
||||
messages: mpsc::Sender<Message>,
|
||||
) -> Result<()> {
|
||||
let path = socket_path().context("Error getting socket path")?;
|
||||
handle_reverse_connections_with_path(messages, path).await
|
||||
}
|
||||
|
||||
async fn handle_reverse_connections_with_path(
|
||||
messages: mpsc::Sender<Message>,
|
||||
path: PathBuf,
|
||||
) -> Result<()> {
|
||||
let _ = std::fs::remove_file(&path);
|
||||
let listener = UnixListener::bind(&path)
|
||||
.with_context(|| format!("Failed to bind to {}", path.display()))?;
|
||||
loop {
|
||||
let (socket, _addr) = listener
|
||||
.accept()
|
||||
.await
|
||||
.context("Error accepting connection")?;
|
||||
|
||||
let sender = messages.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = handle_connection(socket, sender).await {
|
||||
warn!("Error handling socket connection: {:?}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +120,7 @@ mod tests {
|
|||
|
||||
let path_override = path.clone();
|
||||
tokio::spawn(async move {
|
||||
handle_browser_open_with_path(sender, path_override)
|
||||
handle_reverse_connections_with_path(sender, path_override)
|
||||
.await
|
||||
.expect("Error in server!");
|
||||
});
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::browse::handle_browser_open;
|
||||
use crate::message::{Message, MessageReader, MessageWriter};
|
||||
use crate::reverse::handle_reverse_connections;
|
||||
use anyhow::Result;
|
||||
use log::{error, warn};
|
||||
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt, BufReader, BufWriter};
|
||||
|
|
@ -13,7 +13,7 @@ mod refresh;
|
|||
async fn write_driver<Writer: AsyncWrite + Unpin>(
|
||||
messages: &mut mpsc::Receiver<Message>,
|
||||
writer: &mut MessageWriter<Writer>,
|
||||
) -> () {
|
||||
) {
|
||||
while let Some(m) = messages.recv().await {
|
||||
writer.write(m).await.expect("Failed to write the message")
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ async fn server_main<
|
|||
tokio::select! {
|
||||
_ = write_driver(&mut receiver, &mut writer) => Ok(()),
|
||||
r = server_loop(&mut reader, &mut sender) => r,
|
||||
r = handle_browser_open(browse_sender) => r,
|
||||
r = handle_reverse_connections(browse_sender) => r,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue