ssh/channel/local/
channel_exec.rs1use 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 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 pub fn get_output(&mut self) -> SshResult<Vec<u8>> {
52 let r: Vec<u8> = self.recv_to_end()?;
53 Ok(r)
54 }
55
56 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}