ssh/channel/local/
channel_shell.rs1use super::channel::Channel;
2use crate::constant::{ssh_connection_code, ssh_str};
3use crate::error::SshResult;
4use crate::model::{Data, TerminalSize};
5use std::{
6 io::{Read, Write},
7 ops::{Deref, DerefMut},
8};
9
10pub struct ChannelShell<S: Read + Write>(Channel<S>);
11
12impl<S> ChannelShell<S>
13where
14 S: Read + Write,
15{
16 pub(crate) fn open(channel: Channel<S>, tv: TerminalSize) -> SshResult<Self> {
17 let mut channel_shell = ChannelShell(channel);
19 channel_shell.request_pty(tv)?;
20 channel_shell.get_shell()?;
21 Ok(channel_shell)
22 }
23
24 fn request_pty(&mut self, tv: TerminalSize) -> SshResult<()> {
25 let tvs = tv.fetch();
26 let mut data = Data::new();
27 data.put_u8(ssh_connection_code::CHANNEL_REQUEST)
28 .put_u32(self.server_channel_no)
29 .put_str(ssh_str::PTY_REQ)
30 .put_u8(false as u8)
31 .put_str(ssh_str::XTERM_VAR)
32 .put_u32(tvs.0)
33 .put_u32(tvs.1)
34 .put_u32(tvs.2)
35 .put_u32(tvs.3);
36 let model = [
37 128, 0, 1, 0xc2, 0, 129, 0, 1, 0xc2, 0, 0_u8, ];
43 data.put_u8s(&model);
44 self.send(data)
45 }
46
47 fn get_shell(&mut self) -> SshResult<()> {
48 let mut data = Data::new();
49 data.put_u8(ssh_connection_code::CHANNEL_REQUEST)
50 .put_u32(self.server_channel_no)
51 .put_str(ssh_str::SHELL)
52 .put_u8(false as u8);
53 self.send(data)
54 }
55
56 pub fn read(&mut self) -> SshResult<Vec<u8>> {
60 let mut out = self.recv()?;
61 while let Ok(Some(mut data)) = self.try_recv() {
62 out.append(&mut data)
63 }
64 Ok(out)
65 }
66
67 pub fn write(&mut self, buf: &[u8]) -> SshResult<()> {
70 let _ = self.send_data(buf.to_vec())?;
71 Ok(())
72 }
73}
74
75impl<S> Deref for ChannelShell<S>
76where
77 S: Read + Write,
78{
79 type Target = Channel<S>;
80 fn deref(&self) -> &Self::Target {
81 &self.0
82 }
83}
84
85impl<S> DerefMut for ChannelShell<S>
86where
87 S: Read + Write,
88{
89 fn deref_mut(&mut self) -> &mut Self::Target {
90 &mut self.0
91 }
92}