ssh/channel/local/
channel_exec.rs

1use super::channel::Channel;
2use crate::error::SshResult;
3use crate::model::Data;
4use crate::{
5    constant::{ssh_connection_code, ssh_str},
6    SshError,
7};
8use std::{
9    io::{Read, Write},
10    ops::{Deref, DerefMut},
11};
12
13pub struct ChannelExec<S: Read + Write> {
14    channel: Channel<S>,
15    command_send: bool,
16}
17
18impl<S> ChannelExec<S>
19where
20    S: Read + Write,
21{
22    pub(crate) fn open(channel: Channel<S>) -> Self {
23        Self {
24            channel,
25            command_send: false,
26        }
27    }
28
29    /// Send an executable command to the server
30    ///
31    pub fn exec_command(&mut self, command: &str) -> SshResult<()> {
32        if self.command_send {
33            return Err(SshError::GeneralError(
34                "An exec channle can only send one command".to_owned(),
35            ));
36        }
37
38        tracing::debug!("Send command {}", command);
39        self.command_send = true;
40        let mut data = Data::new();
41        data.put_u8(ssh_connection_code::CHANNEL_REQUEST)
42            .put_u32(self.server_channel_no)
43            .put_str(ssh_str::EXEC)
44            .put_u8(true as u8)
45            .put_str(command);
46        self.send(data)
47    }
48
49    /// Get the output of the previous command
50    ///
51    pub fn get_output(&mut self) -> SshResult<Vec<u8>> {
52        let r: Vec<u8> = self.recv_to_end()?;
53        Ok(r)
54    }
55
56    /// Send an executable command to the server
57    /// and get the result
58    ///
59    /// This method also implicitly consume the channel object,
60    /// since the exec channel can only execute one command
61    ///
62    pub fn send_command(mut self, command: &str) -> SshResult<Vec<u8>> {
63        self.exec_command(command)?;
64
65        self.get_output()
66    }
67}
68
69impl<S> Deref for ChannelExec<S>
70where
71    S: Read + Write,
72{
73    type Target = Channel<S>;
74    fn deref(&self) -> &Self::Target {
75        &self.channel
76    }
77}
78
79impl<S> DerefMut for ChannelExec<S>
80where
81    S: Read + Write,
82{
83    fn deref_mut(&mut self) -> &mut Self::Target {
84        &mut self.channel
85    }
86}