diff options
author | Matteo Bigoi <bigo@crisidev.org> | 2020-11-16 12:50:49 +0000 |
---|---|---|
committer | Wez Furlong <wez@wezfurlong.org> | 2020-11-16 17:35:55 -0800 |
commit | 3872d9fae805d83f33c3ac053b6301ea65a744c3 (patch) | |
tree | 565c4ea580e28c1b4ac6287ff3a30fdff93eda79 | |
parent | 9443e31ddd93106033dcd03cf767d2d904db3084 (diff) | |
download | ssh2-rs-3872d9fae805d83f33c3ac053b6301ea65a744c3.zip |
Update documentation to ensure sending and receiving files via SCP wait for the transfer to finish. Add Netconf example
Signed-off-by: Bigo <bigo@crisidev.org>
-rw-r--r-- | src/lib.rs | 84 |
1 files changed, 83 insertions, 1 deletions
@@ -101,9 +101,15 @@ //! sess.handshake().unwrap(); //! sess.userauth_agent("username").unwrap(); //! +//! // Write the file //! let mut remote_file = sess.scp_send(Path::new("remote"), //! 0o644, 10, None).unwrap(); //! remote_file.write(b"1234567890").unwrap(); +//! // Close the channel and wait for the whole content to be tranferred +//! remote_file.send_eof().unwrap(); +//! remote_file.wait_eof().unwrap(); +//! remote_file.close().unwrap(); +//! remote_file.wait_close().unwrap(); //! ``` //! //! ## Download a file @@ -125,7 +131,83 @@ //! println!("remote file size: {}", stat.size()); //! let mut contents = Vec::new(); //! remote_file.read_to_end(&mut contents).unwrap(); -//! // ... +//! +//! // Close the channel and wait for the whole content to be tranferred +//! remote_file.send_eof().unwrap(); +//! remote_file.wait_eof().unwrap(); +//! remote_file.close().unwrap(); +//! remote_file.wait_close().unwrap(); +//! ``` +//! +//! ## Execute a Netconf XML payload +//! +//! ```no_run +//! use ssh2::{Channel, Session}; +//! use std::error::Error; +//! use std::io::prelude::*; +//! use std::net::TcpStream; +//! +//! const HELLO: &str = "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> +//! <capabilities> +//! <capability>urn:ietf:params:netconf:base:1.1</capability> +//! </capabilities> +//! </hello> +//! ]]>]]>"; +//! +//! const PAYLOAD: &str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> +//! <rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.1\" message-id=\"2\"> +//! <cli xmlns=\"http://cisco.com/ns/yang/cisco-nx-os-device\"><mode>EXEC</mode><cmdline>show version</cmdline></cli> +//! </rpc>"; +//! +//! fn read(channel: &mut Channel) -> Result<String, Box<dyn Error>> { +//! let mut result = String::new(); +//! loop { +//! // If you plan to use this, be aware that reading 1 byte at a time is terribly +//! // inefficient and should be optimized for your usecase. This is just an example. +//! let mut buffer = [1u8; 1]; +//! let bytes_read = channel.read(&mut buffer[..])?; +//! let s = String::from_utf8_lossy(&buffer[..bytes_read]); +//! result.push_str(&s); +//! if result.ends_with("]]>]]>") { +//! println!("Found netconf 1.0 terminator, breaking read loop"); +//! break; +//! } +//! if result.ends_with("##") { +//! println!("Found netconf 1.1 terminator, breaking read loop"); +//! break; +//! } +//! if bytes_read == 0 || channel.eof() { +//! println!("Buffer is empty, SSH channel read terminated"); +//! break; +//! } +//! } +//! Ok(result) +//! } +//! +//! fn main() -> Result<(), Box<dyn Error>> { +//! let tcp = TcpStream::connect("127.0.0.1:830")?; +//! let mut sess = Session::new()?; +//! sess.set_tcp_stream(tcp); +//! sess.handshake().unwrap(); +//! sess.userauth_password("user", "pass")?; +//! +//! let mut channel = sess.channel_session()?; +//! channel.subsystem("netconf")?; +//! let result = read(&mut channel)?; +//! println!("Result from connection:\n{}", result); +//! +//! let payload = format!("{}\n#{}\n{}\n##\n", HELLO, PAYLOAD.len(), PAYLOAD); +//! let a = channel.write(payload.as_bytes())?; +//! println!("Written {} bytes payload", a); +//! let result = read(&mut channel)?; +//! println!("Result from payload execution:\n{}", result); +//! +//! channel.send_eof()?; +//! channel.wait_eof()?; +//! channel.close()?; +//! channel.wait_close()?; +//! Ok(()) +//! } //! ``` #![doc(html_root_url = "https://docs.rs/ssh2")] |