Add extra session commands

pull/38/head v0.2.3
Chip Senkbeil 3 years ago
parent 7563855217
commit 3cbdfb19d9
No known key found for this signature in database
GPG Key ID: 35EF1F8EC72A4131

2
Cargo.lock generated

@ -199,7 +199,7 @@ dependencies = [
[[package]]
name = "distant"
version = "0.2.2"
version = "0.2.3"
dependencies = [
"bytes",
"derive_more",

@ -2,7 +2,7 @@
name = "distant"
description = "Operate on a remote computer through file and process manipulation"
categories = ["command-line-utilities"]
version = "0.2.2"
version = "0.2.3"
authors = ["Chip Senkbeil <chip@senkbeil.org>"]
edition = "2018"
homepage = "https://github.com/chipsenkbeil/distant"

@ -82,12 +82,32 @@ impl Subcommand {
pub enum SessionSubcommand {
/// Clears the current session
Clear,
/// Reports whether or not a session exists
Exists,
/// Prints out information about the available sessions
Info {
/// Represents the format that results should be returned
///
/// Currently, there are two possible formats:
/// 1. "json": printing out JSON for external program usage
/// 3. "shell": printing out human-readable results for interactive shell usage
#[structopt(
short,
long,
case_insensitive = true,
default_value = "shell",
possible_values = Mode::VARIANTS
)]
mode: Mode,
},
}
/// Represents the communication medium used for the send command
#[derive(Copy, Clone, Debug, Display, PartialEq, Eq, IsVariant, EnumString, EnumVariantNames)]
#[strum(serialize_all = "snake_case")]
pub enum SendMode {
pub enum Mode {
/// Sends and receives data in JSON format
Json,
@ -110,9 +130,9 @@ pub struct SendSubcommand {
long,
case_insensitive = true,
default_value = "shell",
possible_values = SendMode::VARIANTS
possible_values = Mode::VARIANTS
)]
pub mode: SendMode,
pub mode: Mode,
/// If specified, commands to send are sent over stdin and responses are received
/// over stdout (and stderr if mode is shell)

@ -1,7 +1,7 @@
use crate::{
data::{Request, RequestPayload, Response, ResponsePayload},
net::{Client, TransportError},
opt::{CommonOpt, SendMode, SendSubcommand},
opt::{CommonOpt, Mode, SendSubcommand},
utils::{Session, SessionError},
};
use derive_more::{Display, Error, From};
@ -98,7 +98,7 @@ fn spawn_stdin_reader() -> mpsc::Receiver<String> {
async fn interactive_loop(
mut client: Client,
id: usize,
mode: SendMode,
mode: Mode,
interactive: bool,
) -> Result<(), Error> {
let mut stream = client.to_response_stream();
@ -120,7 +120,7 @@ async fn interactive_loop(
}
// For json mode, all stdin is treated as individual requests
SendMode::Json => {
Mode::Json => {
trace!("Client sending request: {:?}", line);
let result = serde_json::from_str(&line)
.map_err(|x| io::Error::new(io::ErrorKind::InvalidData, x));
@ -141,7 +141,7 @@ async fn interactive_loop(
}
// For interactive shell mode, parse stdin as individual commands
SendMode::Shell if interactive => {
Mode::Shell if interactive => {
if line.trim().is_empty() {
continue;
}
@ -171,7 +171,7 @@ async fn interactive_loop(
}
// For non-interactive shell mode, all stdin is treated as a proc's stdin
SendMode::Shell => {
Mode::Shell => {
trace!("Client sending stdin: {:?}", line);
let req = Request::from(RequestPayload::ProcStdin {
id,
@ -231,14 +231,14 @@ impl ResponseOut {
}
}
fn format_response(mode: SendMode, res: Response) -> io::Result<ResponseOut> {
fn format_response(mode: Mode, res: Response) -> io::Result<ResponseOut> {
Ok(match mode {
SendMode::Json => ResponseOut::Stdout(format!(
Mode::Json => ResponseOut::Stdout(format!(
"{}\n",
serde_json::to_string(&res)
.map_err(|x| io::Error::new(io::ErrorKind::InvalidData, x))?
)),
SendMode::Shell => format_shell(res),
Mode::Shell => format_shell(res),
})
}

@ -1,5 +1,5 @@
use crate::{
opt::{CommonOpt, SessionSubcommand},
opt::{CommonOpt, Mode, SessionSubcommand},
utils::Session,
};
use tokio::io;
@ -9,6 +9,38 @@ pub fn run(cmd: SessionSubcommand, _opt: CommonOpt) -> Result<(), io::Error> {
rt.block_on(async {
match cmd {
SessionSubcommand::Clear => Session::clear().await,
SessionSubcommand::Exists => {
if Session::exists() {
Ok(())
} else {
Err(io::Error::new(
io::ErrorKind::NotFound,
"No session available",
))
}
}
SessionSubcommand::Info { mode } => {
let session = Session::load()
.await
.map_err(|x| io::Error::new(io::ErrorKind::InvalidData, x))?;
match mode {
Mode::Json => {
println!(
"{}",
serde_json::to_string(&serde_json::json!({
"host": session.host,
"port": session.port,
}))
.unwrap()
);
}
Mode::Shell => {
println!("Host: {}", session.host);
println!("Port: {}", session.port);
}
}
Ok(())
}
}
})
}

@ -73,6 +73,11 @@ impl Session {
tokio::fs::remove_file(SESSION_PATH.as_path()).await
}
/// Returns true if a session is available
pub fn exists() -> bool {
SESSION_PATH.exists()
}
/// Saves a session to disk
pub async fn save(&self) -> io::Result<()> {
let key_hex_str = self.to_unprotected_hex_auth_key();

Loading…
Cancel
Save