diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/agent.rs | 62 | ||||
-rw-r--r-- | src/channel.rs | 190 | ||||
-rw-r--r-- | src/error.rs | 33 | ||||
-rw-r--r-- | src/knownhosts.rs | 159 | ||||
-rw-r--r-- | src/lib.rs | 37 | ||||
-rw-r--r-- | src/listener.rs | 10 | ||||
-rw-r--r-- | src/session.rs | 368 | ||||
-rw-r--r-- | src/sftp.rs | 304 | ||||
-rw-r--r-- | src/util.rs | 21 |
9 files changed, 661 insertions, 523 deletions
diff --git a/src/agent.rs b/src/agent.rs index 79b939a..b1f35f5 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -3,8 +3,8 @@ use std::marker; use std::slice; use std::str; -use {raw, Session, Error}; use util::{Binding, SessionBinding}; +use {raw, Error, Session}; /// A structure representing a connection to an SSH agent. /// @@ -47,18 +47,21 @@ impl<'sess> Agent<'sess> { /// Get an iterator over the identities of this agent. pub fn identities(&self) -> Identities { - Identities { prev: 0 as *mut _, agent: self } + Identities { + prev: 0 as *mut _, + agent: self, + } } /// Attempt public key authentication with the help of ssh-agent. - pub fn userauth(&self, username: &str, identity: &PublicKey) - -> Result<(), Error>{ + pub fn userauth(&self, username: &str, identity: &PublicKey) -> Result<(), Error> { let username = try!(CString::new(username)); unsafe { - self.sess.rc(raw::libssh2_agent_userauth(self.raw, - username.as_ptr(), - identity.raw)) - + self.sess.rc(raw::libssh2_agent_userauth( + self.raw, + username.as_ptr(), + identity.raw, + )) } } } @@ -66,11 +69,15 @@ impl<'sess> Agent<'sess> { impl<'sess> SessionBinding<'sess> for Agent<'sess> { type Raw = raw::LIBSSH2_AGENT; - unsafe fn from_raw(sess: &'sess Session, - raw: *mut raw::LIBSSH2_AGENT) -> Agent<'sess> { - Agent { raw: raw, sess: sess } + unsafe fn from_raw(sess: &'sess Session, raw: *mut raw::LIBSSH2_AGENT) -> Agent<'sess> { + Agent { + raw: raw, + sess: sess, + } + } + fn raw(&self) -> *mut raw::LIBSSH2_AGENT { + self.raw } - fn raw(&self) -> *mut raw::LIBSSH2_AGENT { self.raw } } impl<'a> Drop for Agent<'a> { @@ -84,10 +91,11 @@ impl<'agent> Iterator for Identities<'agent> { fn next(&mut self) -> Option<Result<PublicKey<'agent>, Error>> { unsafe { let mut next = 0 as *mut _; - match raw::libssh2_agent_get_identity(self.agent.raw, - &mut next, - self.prev) { - 0 => { self.prev = next; Some(Ok(Binding::from_raw(next))) } + match raw::libssh2_agent_get_identity(self.agent.raw, &mut next, self.prev) { + 0 => { + self.prev = next; + Some(Ok(Binding::from_raw(next))) + } 1 => None, rc => Some(Err(self.agent.sess.rc(rc).err().unwrap())), } @@ -98,28 +106,26 @@ impl<'agent> Iterator for Identities<'agent> { impl<'agent> PublicKey<'agent> { /// Return the data of this public key. pub fn blob(&self) -> &[u8] { - unsafe { - slice::from_raw_parts_mut((*self.raw).blob, - (*self.raw).blob_len as usize) - } + unsafe { slice::from_raw_parts_mut((*self.raw).blob, (*self.raw).blob_len as usize) } } /// Returns the comment in a printable format pub fn comment(&self) -> &str { - unsafe { - str::from_utf8(::opt_bytes(self, (*self.raw).comment).unwrap()) - .unwrap() - } + unsafe { str::from_utf8(::opt_bytes(self, (*self.raw).comment).unwrap()).unwrap() } } } impl<'agent> Binding for PublicKey<'agent> { type Raw = *mut raw::libssh2_agent_publickey; - unsafe fn from_raw(raw: *mut raw::libssh2_agent_publickey) - -> PublicKey<'agent> { - PublicKey { raw: raw, _marker: marker::PhantomData } + unsafe fn from_raw(raw: *mut raw::libssh2_agent_publickey) -> PublicKey<'agent> { + PublicKey { + raw: raw, + _marker: marker::PhantomData, + } } - fn raw(&self) -> *mut raw::libssh2_agent_publickey { self.raw } + fn raw(&self) -> *mut raw::libssh2_agent_publickey { + self.raw + } } diff --git a/src/channel.rs b/src/channel.rs index 32930d8..6328938 100644 --- a/src/channel.rs +++ b/src/channel.rs @@ -1,11 +1,11 @@ +use libc::{c_char, c_int, c_uchar, c_uint, c_ulong, c_void, size_t}; use std::cmp; use std::io::prelude::*; use std::io::{self, ErrorKind}; use std::slice; -use libc::{c_uint, c_int, size_t, c_char, c_void, c_uchar, c_ulong}; -use {raw, Session, Error}; use util::{Binding, SessionBinding}; +use {raw, Error, Session}; /// A channel represents a portion of an SSH connection on which data can be /// read and written. @@ -68,11 +68,13 @@ impl<'sess> Channel<'sess> { /// ignored by the server despite returning success. pub fn setenv(&mut self, var: &str, val: &str) -> Result<(), Error> { unsafe { - self.sess.rc(raw::libssh2_channel_setenv_ex(self.raw, - var.as_ptr() as *const _, - var.len() as c_uint, - val.as_ptr() as *const _, - val.len() as c_uint)) + self.sess.rc(raw::libssh2_channel_setenv_ex( + self.raw, + var.as_ptr() as *const _, + var.len() as c_uint, + val.as_ptr() as *const _, + val.len() as c_uint, + )) } } @@ -83,40 +85,46 @@ impl<'sess> Channel<'sess> { /// /// The dimensions argument is a tuple of (width, height, width_px, /// height_px) - pub fn request_pty(&mut self, term: &str, - mode: Option<&str>, - dim: Option<(u32, u32, u32, u32)>) - -> Result<(), Error>{ + pub fn request_pty( + &mut self, + term: &str, + mode: Option<&str>, + dim: Option<(u32, u32, u32, u32)>, + ) -> Result<(), Error> { self.sess.rc(unsafe { - let (width, height, width_px, height_px) = - dim.unwrap_or((80, 24, 0, 0)); - raw::libssh2_channel_request_pty_ex(self.raw, - term.as_ptr() as *const _, - term.len() as c_uint, - mode.map(|s| s.as_ptr()) - .unwrap_or(0 as *const _) - as *const _, - mode.map(|s| s.len()) - .unwrap_or(0) as c_uint, - width as c_int, - height as c_int, - width_px as c_int, - height_px as c_int) + let (width, height, width_px, height_px) = dim.unwrap_or((80, 24, 0, 0)); + raw::libssh2_channel_request_pty_ex( + self.raw, + term.as_ptr() as *const _, + term.len() as c_uint, + mode.map(|s| s.as_ptr()).unwrap_or(0 as *const _) as *const _, + mode.map(|s| s.len()).unwrap_or(0) as c_uint, + width as c_int, + height as c_int, + width_px as c_int, + height_px as c_int, + ) }) } /// Request a PTY of a specified size - pub fn request_pty_size(&mut self, width: u32, height: u32, - width_px: Option<u32>, height_px: Option<u32>) - -> Result<(), Error> { + pub fn request_pty_size( + &mut self, + width: u32, + height: u32, + width_px: Option<u32>, + height_px: Option<u32>, + ) -> Result<(), Error> { let width_px = width_px.unwrap_or(0); let height_px = height_px.unwrap_or(0); self.sess.rc(unsafe { - raw::libssh2_channel_request_pty_size_ex(self.raw, - width as c_int, - height as c_int, - width_px as c_int, - height_px as c_int) + raw::libssh2_channel_request_pty_size_ex( + self.raw, + width as c_int, + height as c_int, + width_px as c_int, + height_px as c_int, + ) }) } @@ -161,14 +169,17 @@ impl<'sess> Channel<'sess> { /// /// The SSH2 protocol currently defines shell, exec, and subsystem as /// standard process services. - pub fn process_startup(&mut self, request: &str, message: Option<&str>) - -> Result<(), Error> { + pub fn process_startup(&mut self, request: &str, message: Option<&str>) -> Result<(), Error> { let message_len = message.map(|s| s.len()).unwrap_or(0); let message = message.map(|s| s.as_ptr()).unwrap_or(0 as *const _); unsafe { - let rc = raw::libssh2_channel_process_startup(self.raw, - request.as_ptr() as *const _, request.len() as c_uint, - message as *const _, message_len as c_uint); + let rc = raw::libssh2_channel_process_startup( + self.raw, + request.as_ptr() as *const _, + request.len() as c_uint, + message as *const _, + message_len as c_uint, + ); self.sess.rc(rc) } } @@ -190,7 +201,10 @@ impl<'sess> Channel<'sess> { /// * FLUSH_EXTENDED_DATA - Flush all extended data substreams /// * FLUSH_ALL - Flush all substreams pub fn stream<'a>(&'a mut self, stream_id: i32) -> Stream<'a, 'sess> { - Stream { channel: self, id: stream_id } + Stream { + channel: self, + id: stream_id, + } } /// Returns the exit code raised by the process running on the remote host @@ -215,22 +229,27 @@ impl<'sess> Channel<'sess> { let mut msglen = 0; let mut lang = 0 as *mut _; let mut langlen = 0; - let rc = raw::libssh2_channel_get_exit_signal(self.raw, - &mut sig, &mut siglen, - &mut msg, &mut msglen, - &mut lang, - &mut langlen); + let rc = raw::libssh2_channel_get_exit_signal( + self.raw, + &mut sig, + &mut siglen, + &mut msg, + &mut msglen, + &mut lang, + &mut langlen, + ); try!(self.sess.rc(rc)); return Ok(ExitSignal { exit_signal: convert(self, sig, siglen), error_message: convert(self, msg, msglen), lang_tag: convert(self, lang, langlen), - }) + }); } - unsafe fn convert(chan: &Channel, ptr: *mut c_char, - len: size_t) -> Option<String> { - if ptr.is_null() { return None } + unsafe fn convert(chan: &Channel, ptr: *mut c_char, len: size_t) -> Option<String> { + if ptr.is_null() { + return None; + } let slice = slice::from_raw_parts(ptr as *const u8, len as usize); let ret = slice.to_vec(); raw::libssh2_free(chan.sess.raw(), ptr as *mut c_void); @@ -243,9 +262,7 @@ impl<'sess> Channel<'sess> { unsafe { let mut avail = 0; let mut init = 0; - let remaining = raw::libssh2_channel_window_read_ex(self.raw, - &mut avail, - &mut init); + let remaining = raw::libssh2_channel_window_read_ex(self.raw, &mut avail, &mut init); ReadWindow { remaining: remaining as u32, available: avail as u32, @@ -258,8 +275,7 @@ impl<'sess> Channel<'sess> { pub fn write_window(&self) -> WriteWindow { unsafe { let mut init = 0; - let remaining = raw::libssh2_channel_window_write_ex(self.raw, - &mut init); + let remaining = raw::libssh2_channel_window_write_ex(self.raw, &mut init); WriteWindow { remaining: remaining as u32, window_size_initial: init as u32, @@ -274,14 +290,15 @@ impl<'sess> Channel<'sess> { /// /// This function returns the new size of the receive window (as understood /// by remote end) on success. - pub fn adjust_receive_window(&mut self, adjust: u64, force: bool) - -> Result<u64, Error> { + pub fn adjust_receive_window(&mut self, adjust: u64, force: bool) -> Result<u64, Error> { let mut ret = 0; let rc = unsafe { - raw::libssh2_channel_receive_window_adjust2(self.raw, - adjust as c_ulong, - force as c_uchar, - &mut ret) + raw::libssh2_channel_receive_window_adjust2( + self.raw, + adjust as c_ulong, + force as c_uchar, + &mut ret, + ) }; try!(self.sess.rc(rc)); Ok(ret as u64) @@ -296,8 +313,7 @@ impl<'sess> Channel<'sess> { /// Check if the remote host has sent an EOF status for the selected stream. pub fn eof(&self) -> bool { - self.read_limit == Some(0) || - unsafe { raw::libssh2_channel_eof(self.raw) != 0 } + self.read_limit == Some(0) || unsafe { raw::libssh2_channel_eof(self.raw) != 0 } } /// Tell the remote host that no further data will be sent on the specified @@ -305,9 +321,7 @@ impl<'sess> Channel<'sess> { /// /// Processes typically interpret this as a closed stdin descriptor. pub fn send_eof(&mut self) -> Result<(), Error> { - unsafe { - self.sess.rc(raw::libssh2_channel_send_eof(self.raw)) - } + unsafe { self.sess.rc(raw::libssh2_channel_send_eof(self.raw)) } } /// Wait for the remote end to send EOF. @@ -325,9 +339,7 @@ impl<'sess> Channel<'sess> { /// To wait for the remote end to close its connection as well, follow this /// command with `wait_closed` pub fn close(&mut self) -> Result<(), Error> { - unsafe { - self.sess.rc(raw::libssh2_channel_close(self.raw)) - } + unsafe { self.sess.rc(raw::libssh2_channel_close(self.raw)) } } /// Enter a temporary blocking state until the remote host closes the named @@ -342,15 +354,16 @@ impl<'sess> Channel<'sess> { impl<'sess> SessionBinding<'sess> for Channel<'sess> { type Raw = raw::LIBSSH2_CHANNEL; - unsafe fn from_raw(sess: &'sess Session, - raw: *mut raw::LIBSSH2_CHANNEL) -> Channel<'sess> { + unsafe fn from_raw(sess: &'sess Session, raw: *mut raw::LIBSSH2_CHANNEL) -> Channel<'sess> { Channel { raw: raw, sess: sess, read_limit: None, } } - fn raw(&self) -> *mut raw::LIBSSH2_CHANNEL { self.raw } + fn raw(&self) -> *mut raw::LIBSSH2_CHANNEL { + self.raw + } } impl<'sess> Write for Channel<'sess> { @@ -379,7 +392,9 @@ impl<'sess> Drop for Channel<'sess> { impl<'channel, 'sess> Read for Stream<'channel, 'sess> { fn read(&mut self, data: &mut [u8]) -> io::Result<usize> { - if self.channel.eof() { return Ok(0) } + if self.channel.eof() { + return Ok(0); + } let data = match self.channel.read_limit { Some(amt) => { @@ -389,10 +404,12 @@ impl<'channel, 'sess> Read for Stream<'channel, 'sess> { None => data, }; let ret = unsafe { - let rc = raw::libssh2_channel_read_ex(self.channel.raw, - self.id as c_int, - data.as_mut_ptr() as *mut _, - data.len() as size_t); + let rc = raw::libssh2_channel_read_ex( + self.channel.raw, + self.id as c_int, + data.as_mut_ptr() as *mut _, + data.len() as size_t, + ); self.channel.sess.rc(rc as c_int).map(|()| rc as usize) }; match ret { @@ -410,23 +427,22 @@ impl<'channel, 'sess> Read for Stream<'channel, 'sess> { impl<'channel, 'sess> Write for Stream<'channel, 'sess> { fn write(&mut self, data: &[u8]) -> io::Result<usize> { unsafe { - let rc = raw::libssh2_channel_write_ex(self.channel.raw, - self.id as c_int, - data.as_ptr() as *mut _, - data.len() as size_t); + let rc = raw::libssh2_channel_write_ex( + self.channel.raw, + self.id as c_int, + data.as_ptr() as *mut _, + data.len() as size_t, + ); self.channel.sess.rc(rc as c_int).map(|()| rc as usize) - }.map_err(|e| { - io::Error::new(ErrorKind::Other, e) - }) + } + .map_err(|e| io::Error::new(ErrorKind::Other, e)) } fn flush(&mut self) -> io::Result<()> { unsafe { - let rc = raw::libssh2_channel_flush_ex(self.channel.raw, - self.id as c_int); + let rc = raw::libssh2_channel_flush_ex(self.channel.raw, self.id as c_int); self.channel.sess.rc(rc) - }.map_err(|e| { - io::Error::new(ErrorKind::Other, e) - }) + } + .map_err(|e| io::Error::new(ErrorKind::Other, e)) } } diff --git a/src/error.rs b/src/error.rs index 0911e57..1d2c5da 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,11 +1,11 @@ +use libc; use std::error; use std::ffi::NulError; use std::fmt; use std::str; -use libc; -use {raw, Session}; use util::Binding; +use {raw, Session}; /// Representation of an error that can occur within libssh2 #[derive(Debug)] @@ -23,9 +23,10 @@ impl Error { static STATIC: () = (); unsafe { let mut msg = 0 as *mut _; - let rc = raw::libssh2_session_last_error(sess.raw(), &mut msg, - 0 as *mut _, 0); - if rc == 0 { return None } + let rc = raw::libssh2_session_last_error(sess.raw(), &mut msg, 0 as *mut _, 0); + if rc == 0 { + return None; + } let s = ::opt_bytes(&STATIC, msg).unwrap(); Some(Error::new(rc, str::from_utf8(s).unwrap())) } @@ -118,16 +119,20 @@ impl Error { raw::LIBSSH2_FX_NOT_A_DIRECTORY => "not a directory", raw::LIBSSH2_FX_INVALID_FILENAME => "invalid filename", raw::LIBSSH2_FX_LINK_LOOP => "link loop", - _ => "unknown error" + _ => "unknown error", }; Error::new(code, msg) } /// Get the message corresponding to this error - pub fn message(&self) -> &str { self.msg } + pub fn message(&self) -> &str { + self.msg + } /// Return the code for this error - pub fn code(&self) -> libc::c_int { self.code } + pub fn code(&self) -> libc::c_int { + self.code + } } impl fmt::Display for Error { @@ -137,13 +142,17 @@ impl fmt::Display for Error { } impl error::Error for Error { - fn description(&self) -> &str { self.message() } + fn description(&self) -> &str { + self.message() + } } impl From<NulError> for Error { fn from(_: NulError) -> Error { - Error::new(raw::LIBSSH2_ERROR_INVAL, - "provided data contained a nul byte and could not be used \ - as as string") + Error::new( + raw::LIBSSH2_ERROR_INVAL, + "provided data contained a nul byte and could not be used \ + as as string", + ) } } diff --git a/src/knownhosts.rs b/src/knownhosts.rs index d5d93c5..737ff52 100644 --- a/src/knownhosts.rs +++ b/src/knownhosts.rs @@ -1,11 +1,11 @@ +use libc::{c_int, size_t}; use std::ffi::CString; use std::marker; use std::path::Path; use std::str; -use libc::{c_int, size_t}; -use {raw, Session, Error, KnownHostFileKind, CheckResult}; use util::{self, Binding, SessionBinding}; +use {raw, CheckResult, Error, KnownHostFileKind, Session}; /// A set of known hosts which can be used to verify the identity of a remote /// server. @@ -63,62 +63,57 @@ pub struct Host<'kh> { impl<'sess> KnownHosts<'sess> { /// Reads a collection of known hosts from a specified file and adds them to /// the collection of known hosts. - pub fn read_file(&mut self, file: &Path, kind: KnownHostFileKind) - -> Result<u32, Error> { + pub fn read_file(&mut self, file: &Path, kind: KnownHostFileKind) -> Result<u32, Error> { let file = try!(CString::new(try!(util::path2bytes(file)))); - let n = unsafe { - raw::libssh2_knownhost_readfile(self.raw, file.as_ptr(), - kind as c_int) - }; - if n < 0 { try!(self.sess.rc(n)) } + let n = unsafe { raw::libssh2_knownhost_readfile(self.raw, file.as_ptr(), kind as c_int) }; + if n < 0 { + try!(self.sess.rc(n)) + } Ok(n as u32) } /// Read a line as if it were from a known hosts file. - pub fn read_str(&mut self, s: &str, kind: KnownHostFileKind) - -> Result<(), Error> { + pub fn read_str(&mut self, s: &str, kind: KnownHostFileKind) -> Result<(), Error> { self.sess.rc(unsafe { - raw::libssh2_knownhost_readline(self.raw, - s.as_ptr() as *const _, - s.len() as size_t, - kind as c_int) + raw::libssh2_knownhost_readline( + self.raw, + s.as_ptr() as *const _, + s.len() as size_t, + kind as c_int, + ) }) } /// Writes all the known hosts to the specified file using the specified /// file format. - pub fn write_file(&self, file: &Path, kind: KnownHostFileKind) - -> Result<(), Error> { + pub fn write_file(&self, file: &Path, kind: KnownHostFileKind) -> Result<(), Error> { let file = try!(CString::new(try!(util::path2bytes(file)))); - let n = unsafe { - raw::libssh2_knownhost_writefile(self.raw, file.as_ptr(), - kind as c_int) - }; + let n = unsafe { raw::libssh2_knownhost_writefile(self.raw, file.as_ptr(), kind as c_int) }; self.sess.rc(n) } /// Converts a single known host to a single line of output for storage, /// using the 'type' output format. - pub fn write_string(&self, host: &Host, kind: KnownHostFileKind) - -> Result<String, Error> { + pub fn write_string(&self, host: &Host, kind: KnownHostFileKind) -> Result<String, Error> { let mut v = Vec::with_capacity(128); loop { let mut outlen = 0; unsafe { - let rc = raw::libssh2_knownhost_writeline(self.raw, - host.raw, - v.as_mut_ptr() - as *mut _, - v.capacity() as size_t, - &mut outlen, - kind as c_int); + let rc = raw::libssh2_knownhost_writeline( + self.raw, + host.raw, + v.as_mut_ptr() as *mut _, + v.capacity() as size_t, + &mut outlen, + kind as c_int, + ); if rc == raw::LIBSSH2_ERROR_BUFFER_TOO_SMALL { // + 1 for the trailing zero v.reserve(outlen as usize + 1); } else { try!(self.sess.rc(rc)); v.set_len(outlen as usize); - break + break; } } } @@ -127,14 +122,16 @@ impl<'sess> KnownHosts<'sess> { /// Create an iterator over all of the known hosts in this structure. pub fn iter(&self) -> Hosts { - Hosts { prev: 0 as *mut _, hosts: self } + Hosts { + prev: 0 as *mut _, + hosts: self, + } } /// Delete a known host entry from the collection of known hosts. pub fn remove(&self, host: Host) -> Result<(), Error> { - self.sess.rc(unsafe { - raw::libssh2_knownhost_del(self.raw, host.raw) - }) + self.sess + .rc(unsafe { raw::libssh2_knownhost_del(self.raw, host.raw) }) } /// Checks a host and its associated key against the collection of known @@ -153,16 +150,17 @@ impl<'sess> KnownHosts<'sess> { fn check_port_(&self, host: &str, port: i32, key: &[u8]) -> CheckResult { let host = CString::new(host).unwrap(); - let flags = raw::LIBSSH2_KNOWNHOST_TYPE_PLAIN | - raw::LIBSSH2_KNOWNHOST_KEYENC_RAW; + let flags = raw::LIBSSH2_KNOWNHOST_TYPE_PLAIN | raw::LIBSSH2_KNOWNHOST_KEYENC_RAW; unsafe { - let rc = raw::libssh2_knownhost_checkp(self.raw, - host.as_ptr(), - port as c_int, - key.as_ptr() as *const _, - key.len() as size_t, - flags, - 0 as *mut _); + let rc = raw::libssh2_knownhost_checkp( + self.raw, + host.as_ptr(), + port as c_int, + key.as_ptr() as *const _, + key.len() as size_t, + flags, + 0 as *mut _, + ); match rc { raw::LIBSSH2_KNOWNHOST_CHECK_MATCH => CheckResult::Match, raw::LIBSSH2_KNOWNHOST_CHECK_MISMATCH => CheckResult::Mismatch, @@ -182,23 +180,28 @@ impl<'sess> KnownHosts<'sess> { /// For example: "[host.example.com]:222". /// /// The key provided must be the raw key for the host. - pub fn add(&mut self, host: &str, key: &[u8], comment: &str, - fmt: ::KnownHostKeyFormat) - -> Result<(), Error> { + pub fn add( + &mut self, + host: &str, + key: &[u8], + comment: &str, + fmt: ::KnownHostKeyFormat, + ) -> Result<(), Error> { let host = try!(CString::new(host)); - let flags = raw::LIBSSH2_KNOWNHOST_TYPE_PLAIN | - raw::LIBSSH2_KNOWNHOST_KEYENC_RAW | - (fmt as c_int); + let flags = + raw::LIBSSH2_KNOWNHOST_TYPE_PLAIN | raw::LIBSSH2_KNOWNHOST_KEYENC_RAW | (fmt as c_int); unsafe { - let rc = raw::libssh2_knownhost_addc(self.raw, - host.as_ptr() as *mut _, - 0 as *mut _, - key.as_ptr() as *mut _, - key.len() as size_t, - comment.as_ptr() as *const _, - comment.len() as size_t, - flags, - 0 as *mut _); + let rc = raw::libssh2_knownhost_addc( + self.raw, + host.as_ptr() as *mut _, + 0 as *mut _, + key.as_ptr() as *mut _, + key.len() as size_t, + comment.as_ptr() as *const _, + comment.len() as size_t, + flags, + 0 as *mut _, + ); self.sess.rc(rc) } } @@ -207,17 +210,20 @@ impl<'sess> KnownHosts<'sess> { impl<'sess> SessionBinding<'sess> for KnownHosts<'sess> { type Raw = raw::LIBSSH2_KNOWNHOSTS; - unsafe fn from_raw(sess: &'sess Session, raw: *mut raw::LIBSSH2_KNOWNHOSTS) - -> KnownHosts<'sess> { + unsafe fn from_raw( + sess: &'sess Session, + raw: *mut raw::LIBSSH2_KNOWNHOSTS, + ) -> KnownHosts<'sess> { KnownHosts { raw: raw, sess: sess, } } - fn raw(&self) -> *mut raw::LIBSSH2_KNOWNHOSTS { self.raw } + fn raw(&self) -> *mut raw::LIBSSH2_KNOWNHOSTS { + self.raw + } } - impl<'sess> Drop for KnownHosts<'sess> { fn drop(&mut self) { unsafe { raw::libssh2_knownhost_free(self.raw) } @@ -229,10 +235,11 @@ impl<'kh> Iterator for Hosts<'kh> { fn next(&mut self) -> Option<Result<Host<'kh>, Error>> { unsafe { let mut next = 0 as *mut _; - match raw::libssh2_knownhost_get(self.hosts.raw, - &mut next, - self.prev) { - 0 => { self.prev = next; Some(Ok(Binding::from_raw(next))) } + match raw::libssh2_knownhost_get(self.hosts.raw, &mut next, self.prev) { + 0 => { + self.prev = next; + Some(Ok(Binding::from_raw(next))) + } 1 => None, rc => Some(Err(self.hosts.sess.rc(rc).err().unwrap())), } @@ -243,17 +250,12 @@ impl<'kh> Iterator for Hosts<'kh> { impl<'kh> Host<'kh> { /// This is `None` if no plain text host name exists. pub fn name(&self) -> Option<&str> { - unsafe { - ::opt_bytes(self, (*self.raw).name) - .and_then(|s| str::from_utf8(s).ok()) - } + unsafe { ::opt_bytes(self, (*self.raw).name).and_then(|s| str::from_utf8(s).ok()) } } /// Returns the key in base64/printable format pub fn key(&self) -> &str { - let bytes = unsafe { - ::opt_bytes(self, (*self.raw).key).unwrap() - }; + let bytes = unsafe { ::opt_bytes(self, (*self.raw).key).unwrap() }; str::from_utf8(bytes).unwrap() } } @@ -262,7 +264,12 @@ impl<'kh> Binding for Host<'kh> { type Raw = *mut raw::libssh2_knownhost; unsafe fn from_raw(raw: *mut raw::libssh2_knownhost) -> Host<'kh> { - Host { raw: raw, _marker: marker::PhantomData } + Host { + raw: raw, + _marker: marker::PhantomData, + } + } + fn raw(&self) -> *mut raw::libssh2_knownhost { + self.raw } - fn raw(&self) -> *mut raw::libssh2_knownhost { self.raw } } @@ -129,26 +129,27 @@ #![deny(missing_docs, unused_results)] #![cfg_attr(test, deny(warnings))] -extern crate libssh2_sys as raw; extern crate libc; -#[macro_use] extern crate bitflags; +extern crate libssh2_sys as raw; +#[macro_use] +extern crate bitflags; use std::ffi::CStr; pub use agent::{Agent, Identities, PublicKey}; -pub use channel::{Channel, ExitSignal, ReadWindow, WriteWindow, Stream}; +pub use channel::{Channel, ExitSignal, ReadWindow, Stream, WriteWindow}; pub use error::Error; -pub use knownhosts::{KnownHosts, Hosts, Host}; +pub use knownhosts::{Host, Hosts, KnownHosts}; pub use listener::Listener; -pub use session::{Session, ScpFileStat}; -pub use sftp::{Sftp, OpenFlags, RenameFlags}; -pub use sftp::{OpenType, File, FileStat, FileType}; +pub use session::{ScpFileStat, Session}; +pub use sftp::{File, FileStat, FileType, OpenType}; +pub use sftp::{OpenFlags, RenameFlags, Sftp}; +pub use DisconnectCode::{AuthCancelledByUser, TooManyConnections}; +pub use DisconnectCode::{ByApplication, ConnectionLost, HostKeyNotVerifiable}; +pub use DisconnectCode::{CompressionError, KeyExchangeFailed, MacError, Reserved}; pub use DisconnectCode::{HostNotAllowedToConnect, ProtocolError}; -pub use DisconnectCode::{KeyExchangeFailed, Reserved, MacError, CompressionError}; -pub use DisconnectCode::{ServiceNotAvailable, ProtocolVersionNotSupported}; -pub use DisconnectCode::{HostKeyNotVerifiable, ConnectionLost, ByApplication}; -pub use DisconnectCode::{TooManyConnections, AuthCancelledByUser}; -pub use DisconnectCode::{NoMoreAuthMethodsAvailable, IllegalUserName}; +pub use DisconnectCode::{IllegalUserName, NoMoreAuthMethodsAvailable}; +pub use DisconnectCode::{ProtocolVersionNotSupported, ServiceNotAvailable}; mod agent; mod channel; @@ -166,8 +167,7 @@ pub fn init() { raw::init(); } -unsafe fn opt_bytes<'a, T>(_: &'a T, - c: *const libc::c_char) -> Option<&'a [u8]> { +unsafe fn opt_bytes<'a, T>(_: &'a T, c: *const libc::c_char) -> Option<&'a [u8]> { if c.is_null() { None } else { @@ -178,23 +178,20 @@ unsafe fn opt_bytes<'a, T>(_: &'a T, #[allow(missing_docs)] #[derive(Copy, Clone)] pub enum DisconnectCode { - HostNotAllowedToConnect = - raw::SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT as isize, + HostNotAllowedToConnect = raw::SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT as isize, ProtocolError = raw::SSH_DISCONNECT_PROTOCOL_ERROR as isize, KeyExchangeFailed = raw::SSH_DISCONNECT_KEY_EXCHANGE_FAILED as isize, Reserved = raw::SSH_DISCONNECT_RESERVED as isize, MacError = raw::SSH_DISCONNECT_MAC_ERROR as isize, CompressionError = raw::SSH_DISCONNECT_COMPRESSION_ERROR as isize, ServiceNotAvailable = raw::SSH_DISCONNECT_SERVICE_NOT_AVAILABLE as isize, - ProtocolVersionNotSupported = - raw::SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED as isize, + ProtocolVersionNotSupported = raw::SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED as isize, HostKeyNotVerifiable = raw::SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE as isize, ConnectionLost = raw::SSH_DISCONNECT_CONNECTION_LOST as isize, ByApplication = raw::SSH_DISCONNECT_BY_APPLICATION as isize, TooManyConnections = raw::SSH_DISCONNECT_TOO_MANY_CONNECTIONS as isize, AuthCancelledByUser = raw::SSH_DISCONNECT_AUTH_CANCELLED_BY_USER as isize, - NoMoreAuthMethodsAvailable = - raw::SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE as isize, + NoMoreAuthMethodsAvailable = raw::SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE as isize, IllegalUserName = raw::SSH_DISCONNECT_ILLEGAL_USER_NAME as isize, } diff --git a/src/listener.rs b/src/listener.rs index f9dab07..33a8d5c 100644 --- a/src/listener.rs +++ b/src/listener.rs @@ -1,5 +1,5 @@ -use {raw, Session, Error, Channel}; use util::SessionBinding; +use {raw, Channel, Error, Session}; /// A listener represents a forwarding port from the remote server. /// @@ -23,14 +23,15 @@ impl<'sess> Listener<'sess> { impl<'sess> SessionBinding<'sess> for Listener<'sess> { type Raw = raw::LIBSSH2_LISTENER; - unsafe fn from_raw(sess: &'sess Session, - raw: *mut raw::LIBSSH2_LISTENER) -> Listener<'sess> { + unsafe fn from_raw(sess: &'sess Session, raw: *mut raw::LIBSSH2_LISTENER) -> Listener<'sess> { Listener { raw: raw, sess: sess, } } - fn raw(&self) -> *mut raw::LIBSSH2_LISTENER { self.raw } + fn raw(&self) -> *mut raw::LIBSSH2_LISTENER { + self.raw + } } impl<'sess> Drop for Listener<'sess> { @@ -40,4 +41,3 @@ impl<'sess> Drop for Listener<'sess> { } } } - diff --git a/src/session.rs b/src/session.rs index 4465eb0..71af745 100644 --- a/src/session.rs +++ b/src/session.rs @@ -1,16 +1,16 @@ +#[cfg(unix)] +use libc::size_t; +use libc::{self, c_int, c_long, c_uint, c_void}; use std::ffi::CString; use std::mem; use std::net::TcpStream; use std::path::Path; use std::slice; use std::str; -use libc::{self, c_uint, c_int, c_void, c_long}; -#[cfg(unix)] -use libc::size_t; -use {raw, Error, DisconnectCode, ByApplication, HostKeyType}; -use {MethodType, Agent, Channel, Listener, HashType, KnownHosts, Sftp}; use util::{self, Binding, SessionBinding}; +use {raw, ByApplication, DisconnectCode, Error, HostKeyType}; +use {Agent, Channel, HashType, KnownHosts, Listener, MethodType, Sftp}; /// An SSH session, typically representing one TCP connection. /// @@ -39,9 +39,12 @@ impl Session { pub fn new() -> Option<Session> { ::init(); unsafe { - let ret = raw::libssh2_session_init_ex(None, None, None, - 0 as *mut _); - if ret.is_null() {None} else {Some(Binding::from_raw(ret))} + let ret = raw::libssh2_session_init_ex(None, None, None, 0 as *mut _); + if ret.is_null() { + None + } else { + Some(Binding::from_raw(ret)) + } } } @@ -53,9 +56,7 @@ impl Session { /// default. pub fn set_banner(&self, banner: &str) -> Result<(), Error> { let banner = try!(CString::new(banner)); - unsafe { - self.rc(raw::libssh2_session_banner_set(self.raw, banner.as_ptr())) - } + unsafe { self.rc(raw::libssh2_session_banner_set(self.raw, banner.as_ptr())) } } /// Flag indicating whether SIGPIPE signals will be allowed or blocked. @@ -66,9 +67,11 @@ impl Session { /// layer. pub fn set_allow_sigpipe(&self, block: bool) { let res = unsafe { - self.rc(raw::libssh2_session_flag(self.raw, - raw::LIBSSH2_FLAG_SIGPIPE as c_int, - block as c_int)) + self.rc(raw::libssh2_session_flag( + self.raw, + raw::LIBSSH2_FLAG_SIGPIPE as c_int, + block as c_int, + )) }; res.unwrap(); } @@ -81,9 +84,11 @@ impl Session { /// libssh2 will not attempt to use compression. pub fn set_compress(&self, compress: bool) { let res = unsafe { - self.rc(raw::libssh2_session_flag(self.raw, - raw::LIBSSH2_FLAG_COMPRESS as c_int, - compress as c_int)) + self.rc(raw::libssh2_session_flag( + self.raw, + raw::LIBSSH2_FLAG_COMPRESS as c_int, + compress as c_int, + )) }; res.unwrap(); } @@ -98,9 +103,7 @@ impl Session { /// a blocking session will wait for room. A non-blocking session will /// return immediately without writing anything. pub fn set_blocking(&self, blocking: bool) { - unsafe { - raw::libssh2_session_set_blocking(self.raw, blocking as c_int) - } + unsafe { raw::libssh2_session_set_blocking(self.raw, blocking as c_int) } } /// Returns whether the session was previously set to nonblocking. @@ -144,15 +147,13 @@ impl Session { } #[cfg(windows)] - unsafe fn handshake(raw: *mut raw::LIBSSH2_SESSION, stream: &TcpStream) - -> libc::c_int { + unsafe fn handshake(raw: *mut raw::LIBSSH2_SESSION, stream: &TcpStream) -> libc::c_int { use std::os::windows::prelude::*; raw::libssh2_session_handshake(raw, stream.as_raw_socket()) } #[cfg(unix)] - unsafe fn handshake(raw: *mut raw::LIBSSH2_SESSION, stream: &TcpStream) - -> libc::c_int { + unsafe fn handshake(raw: *mut raw::LIBSSH2_SESSION, stream: &TcpStream) -> libc::c_int { use std::os::unix::prelude::*; raw::libssh2_session_handshake(raw, stream.as_raw_fd()) } @@ -164,15 +165,16 @@ impl Session { /// authentication actually have it disabled and use Keyboard Interactive /// authentication (routed via PAM or another authentication backed) /// instead. - pub fn userauth_password(&self, username: &str, password: &str) - -> Result<(), Error> { + pub fn userauth_password(&self, username: &str, password: &str) -> Result<(), Error> { self.rc(unsafe { - raw::libssh2_userauth_password_ex(self.raw, - username.as_ptr() as *const _, - username.len() as c_uint, - password.as_ptr() as *const _, - password.len() as c_uint, - None) + raw::libssh2_userauth_password_ex( + self.raw, + username.as_ptr() as *const _, + username.len() as c_uint, + password.as_ptr() as *const _, + password.len() as c_uint, + None, + ) }) } @@ -188,19 +190,25 @@ impl Session { try!(agent.list_identities()); let identity = match agent.identities().next() { Some(identity) => try!(identity), - None => return Err(Error::new(raw::LIBSSH2_ERROR_INVAL as c_int, - "no identities found in the ssh agent")) + None => { + return Err(Error::new( + raw::LIBSSH2_ERROR_INVAL as c_int, + "no identities found in the ssh agent", + )) + } }; agent.userauth(username, &identity) } /// Attempt public key authentication using a PEM encoded private key file /// stored on disk. - pub fn userauth_pubkey_file(&self, - username: &str, - pubkey: Option<&Path>, - privatekey: &Path, - passphrase: Option<&str>) -> Result<(), Error> { + pub fn userauth_pubkey_file( + &self, + username: &str, + pubkey: Option<&Path>, + privatekey: &Path, + passphrase: Option<&str>, + ) -> Result<(), Error> { let pubkey = match pubkey { Some(s) => Some(try!(CString::new(try!(util::path2bytes(s))))), None => None, @@ -211,13 +219,17 @@ impl Session { None => None, }; self.rc(unsafe { - raw::libssh2_userauth_publickey_fromfile_ex(self.raw, - username.as_ptr() as *const _, - username.len() as c_uint, - pubkey.as_ref().map(|s| s.as_ptr()).unwrap_or(0 as *const _), - privatekey.as_ptr(), - passphrase.as_ref().map(|s| s.as_ptr()) - .unwrap_or(0 as *const _)) + raw::libssh2_userauth_publickey_fromfile_ex( + self.raw, + username.as_ptr() as *const _, + username.len() as c_uint, + pubkey.as_ref().map(|s| s.as_ptr()).unwrap_or(0 as *const _), + privatekey.as_ptr(), + passphrase + .as_ref() + .map(|s| s.as_ptr()) + .unwrap_or(0 as *const _), + ) }) } @@ -227,11 +239,13 @@ impl Session { /// It is therefore recommended to use `#[cfg(unix)]` or otherwise test for /// the `unix` compliation target when using this function. #[cfg(unix)] - pub fn userauth_pubkey_memory(&self, - username: &str, - pubkeydata: Option<&str>, - privatekeydata: &str, - passphrase: Option<&str>) -> Result<(), Error> { + pub fn userauth_pubkey_memory( + &self, + username: &str, + pubkeydata: Option<&str>, + privatekeydata: &str, + passphrase: Option<&str>, + ) -> Result<(), Error> { let (pubkeydata, pubkeydata_len) = match pubkeydata { Some(s) => (Some(try!(CString::new(s))), s.len()), None => (None, 0), @@ -243,28 +257,36 @@ impl Session { None => None, }; self.rc(unsafe { - raw::libssh2_userauth_publickey_frommemory(self.raw, - username.as_ptr() as *const _, - username.len() as size_t, - pubkeydata.as_ref().map(|s| s.as_ptr()).unwrap_or(0 as *const _), - pubkeydata_len as size_t, - privatekeydata.as_ptr(), - privatekeydata_len as size_t, - passphrase.as_ref().map(|s| s.as_ptr()) - .unwrap_or(0 as *const _)) + raw::libssh2_userauth_publickey_frommemory( + self.raw, + username.as_ptr() as *const _, + username.len() as size_t, + pubkeydata + .as_ref() + .map(|s| s.as_ptr()) + .unwrap_or(0 as *const _), + pubkeydata_len as size_t, + privatekeydata.as_ptr(), + privatekeydata_len as size_t, + passphrase + .as_ref() + .map(|s| s.as_ptr()) + .unwrap_or(0 as *const _), + ) }) } // Umm... I wish this were documented in libssh2? #[allow(missing_docs)] - pub fn userauth_hostbased_file(&self, - username: &str, - publickey: &Path, - privatekey: &Path, - passphrase: Option<&str>, - hostname: &str, - local_username: Option<&str>) - -> Result<(), Error> { + pub fn userauth_hostbased_file( + &self, + username: &str, + publickey: &Path, + privatekey: &Path, + passphrase: Option<&str>, + hostname: &str, + local_username: Option<&str>, + ) -> Result<(), Error> { let publickey = try!(CString::new(try!(util::path2bytes(publickey)))); let privatekey = try!(CString::new(try!(util::path2bytes(privatekey)))); let passphrase = match passphrase { @@ -276,17 +298,21 @@ impl Session { None => username, }; self.rc(unsafe { - raw::libssh2_userauth_hostbased_fromfile_ex(self.raw, - username.as_ptr() as *const _, - username.len() as c_uint, - publickey.as_ptr(), - privatekey.as_ptr(), - passphrase.as_ref().map(|s| s.as_ptr()) - .unwrap_or(0 as *const _), - hostname.as_ptr() as *const _, - hostname.len() as c_uint, - local_username.as_ptr() as *const _, - local_username.len() as c_uint) + raw::libssh2_userauth_hostbased_fromfile_ex( + self.raw, + username.as_ptr() as *const _, + username.len() as c_uint, + publickey.as_ptr(), + privatekey.as_ptr(), + passphrase + .as_ref() + .map(|s| s.as_ptr()) + .unwrap_or(0 as *const _), + hostname.as_ptr() as *const _, + hostname.len() as c_uint, + local_username.as_ptr() as *const _, + local_username.len() as c_uint, + ) }) } @@ -310,8 +336,7 @@ impl Session { let len = username.len(); let username = try!(CString::new(username)); unsafe { - let ret = raw::libssh2_userauth_list(self.raw, username.as_ptr(), - len as c_uint); + let ret = raw::libssh2_userauth_list(self.raw, username.as_ptr(), len as c_uint); if ret.is_null() { Err(Error::last_error(self).unwrap()) } else { @@ -327,14 +352,14 @@ impl Session { /// listed last. If a method is listed which is not supported by libssh2 it /// will be ignored and not sent to the remote host during protocol /// negotiation. - pub fn method_pref(&self, - method_type: MethodType, - prefs: &str) -> Result<(), Error> { + pub fn method_pref(&self, method_type: MethodType, prefs: &str) -> Result<(), Error> { let prefs = try!(CString::new(prefs)); unsafe { - self.rc(raw::libssh2_session_method_pref(self.raw, - method_type as c_int, - prefs.as_ptr())) + self.rc(raw::libssh2_session_method_pref( + self.raw, + method_type as c_int, + prefs.as_ptr(), + )) } } @@ -344,23 +369,22 @@ impl Session { /// parameter. May return `None` if the session has not yet been started. pub fn methods(&self, method_type: MethodType) -> Option<&str> { unsafe { - let ptr = raw::libssh2_session_methods(self.raw, - method_type as c_int); + let ptr = raw::libssh2_session_methods(self.raw, method_type as c_int); ::opt_bytes(self, ptr).and_then(|s| str::from_utf8(s).ok()) } } /// Get list of supported algorithms. - pub fn supported_algs(&self, method_type: MethodType) - -> Result<Vec<&'static str>, Error> { + pub fn supported_algs(&self, method_type: MethodType) -> Result<Vec<&'static str>, Error> { static STATIC: () = (); let method_type = method_type as c_int; let mut ret = Vec::new(); unsafe { let mut ptr = 0 as *mut _; - let rc = raw::libssh2_session_supported_algs(self.raw, method_type, - &mut ptr); - if rc <= 0 { try!(self.rc(rc)) } + let rc = raw::libssh2_session_supported_algs(self.raw, method_type, &mut ptr); + if rc <= 0 { + try!(self.rc(rc)) + } for i in 0..(rc as isize) { let s = ::opt_bytes(&STATIC, *ptr.offset(i)).unwrap();; let s = str::from_utf8(s).unwrap(); @@ -375,9 +399,7 @@ impl Session { /// /// The returned agent will still need to be connected manually before use. pub fn agent(&self) -> Result<Agent, Error> { - unsafe { - SessionBinding::from_raw_opt(self, raw::libssh2_agent_init(self.raw)) - } + unsafe { SessionBinding::from_raw_opt(self, raw::libssh2_agent_init(self.raw)) } } /// Init a collection of known hosts for this session. @@ -396,9 +418,12 @@ impl Session { /// This method is commonly used to create a channel to execute commands /// over or create a new login shell. pub fn channel_session(&self) -> Result<Channel, Error> { - self.channel_open("session", - raw::LIBSSH2_CHANNEL_WINDOW_DEFAULT as u32, - raw::LIBSSH2_CHANNEL_PACKET_DEFAULT as u32, None) + self.channel_open( + "session", + raw::LIBSSH2_CHANNEL_WINDOW_DEFAULT as u32, + raw::LIBSSH2_CHANNEL_PACKET_DEFAULT as u32, + None, + ) } /// Tunnel a TCP connection through an SSH session. @@ -413,18 +438,23 @@ impl Session { /// /// The `Channel` returned represents a connection between this host and the /// specified remote host. - pub fn channel_direct_tcpip(&self, host: &str, port: u16, - src: Option<(&str, u16)>) - -> Result<Channel, Error> { + pub fn channel_direct_tcpip( + &self, + host: &str, + port: u16, + src: Option<(&str, u16)>, + ) -> Result<Channel, Error> { let (shost, sport) = src.unwrap_or(("127.0.0.1", 22)); let host = try!(CString::new(host)); let shost = try!(CString::new(shost)); unsafe { - let ret = raw::libssh2_channel_direct_tcpip_ex(self.raw, - host.as_ptr(), - port as c_int, - shost.as_ptr(), - sport as c_int); + let ret = raw::libssh2_channel_direct_tcpip_ex( + self.raw, + host.as_ptr(), + port as c_int, + shost.as_ptr(), + sport as c_int, + ); SessionBinding::from_raw_opt(self, ret) } } @@ -434,20 +464,21 @@ impl Session { /// /// New connections will be queued by the library until accepted by the /// `accept` method on the returned `Listener`. - pub fn channel_forward_listen(&self, - remote_port: u16, - host: Option<&str>, - queue_maxsize: Option<u32>) - -> Result<(Listener, u16), Error> { + pub fn channel_forward_listen( + &self, + remote_port: u16, + host: Option<&str>, + queue_maxsize: Option<u32>, + ) -> Result<(Listener, u16), Error> { let mut bound_port = 0; unsafe { let ret = raw::libssh2_channel_forward_listen_ex( - self.raw, - host.map(|s| s.as_ptr()).unwrap_or(0 as *const _) - as *mut _, - remote_port as c_int, - &mut bound_port, - queue_maxsize.unwrap_or(0) as c_int); + self.raw, + host.map(|s| s.as_ptr()).unwrap_or(0 as *const _) as *mut _, + remote_port as c_int, + &mut bound_port, + queue_maxsize.unwrap_or(0) as c_int, + ); SessionBinding::from_raw_opt(self, ret).map(|l| (l, bound_port as u16)) } } @@ -457,8 +488,7 @@ impl Session { /// The path specified is a path on the remote host which will attempt to be /// sent over the returned channel. Some stat information is also returned /// about the remote file to prepare for receiving the file. - pub fn scp_recv(&self, path: &Path) - -> Result<(Channel, ScpFileStat), Error> { + pub fn scp_recv(&self, path: &Path) -> Result<(Channel, ScpFileStat), Error> { let path = try!(CString::new(try!(util::path2bytes(path)))); unsafe { let mut sb: libc::stat = mem::zeroed(); @@ -483,18 +513,24 @@ impl Session { /// /// The size of the file, `size`, must be known ahead of time before /// transmission. - pub fn scp_send(&self, remote_path: &Path, mode: i32, - size: u64, times: Option<(u64, u64)>) - -> Result<Channel, Error> { + pub fn scp_send( + &self, + remote_path: &Path, + mode: i32, + size: u64, + times: Option<(u64, u64)>, + ) -> Result<Channel, Error> { let path = try!(CString::new(try!(util::path2bytes(remote_path)))); let (mtime, atime) = times.unwrap_or((0, 0)); unsafe { - let ret = raw::libssh2_scp_send64(self.raw, - path.as_ptr(), - mode as c_int, - size as i64, - mtime as libc::time_t, - atime as libc::time_t); + let ret = raw::libssh2_scp_send64( + self.raw, + path.as_ptr(), + mode as c_int, + size as i64, + mtime as libc::time_t, + atime as libc::time_t, + ); SessionBinding::from_raw_opt(self, ret) } } @@ -516,20 +552,27 @@ impl Session { /// /// This is typically not called directly but rather through /// `channel_session`, `channel_direct_tcpip`, or `channel_forward_listen`. - pub fn channel_open(&self, channel_type: &str, - window_size: u32, packet_size: u32, - message: Option<&str>) -> Result<Channel, Error> { + pub fn channel_open( + &self, + channel_type: &str, + window_size: u32, + packet_size: u32, + message: Option<&str>, + ) -> Result<Channel, Error> { let message_len = message.map(|s| s.len()).unwrap_or(0); unsafe { - let ret = raw::libssh2_channel_open_ex(self.raw, - channel_type.as_ptr() as *const _, - channel_type.len() as c_uint, - window_size as c_uint, - packet_size as c_uint, - message.as_ref().map(|s| s.as_ptr()) - .unwrap_or(0 as *const _) - as *const _, - message_len as c_uint); + let ret = raw::libssh2_channel_open_ex( + self.raw, + channel_type.as_ptr() as *const _, + channel_type.len() as c_uint, + window_size as c_uint, + packet_size as c_uint, + message + .as_ref() + .map(|s| s.as_ptr()) + .unwrap_or(0 as *const _) as *const _, + message_len as c_uint, + ); SessionBinding::from_raw_opt(self, ret) } } @@ -560,7 +603,9 @@ impl Session { let mut kind = 0; unsafe { let ret = raw::libssh2_session_hostkey(self.raw, &mut len, &mut kind); - if ret.is_null() { return None } + if ret.is_null() { + return None; + } let data = slice::from_raw_parts(ret as *const u8, len as usize); let kind = match kind { raw::LIBSSH2_HOSTKEY_TYPE_RSA => HostKeyType::Rsa, @@ -606,10 +651,7 @@ impl Session { /// I/O, use 0 (the default) to disable keepalives. To avoid some busy-loop /// corner-cases, if you specify an interval of 1 it will be treated as 2. pub fn set_keepalive(&self, want_reply: bool, interval: u32) { - unsafe { - raw::libssh2_keepalive_config(self.raw, want_reply as c_int, - interval as c_uint) - } + unsafe { raw::libssh2_keepalive_config(self.raw, want_reply as c_int, interval as c_uint) } } /// Send a keepalive message if needed. @@ -629,18 +671,22 @@ impl Session { /// along with a reason symbol and a verbose description. /// /// Note that this does *not* close the underlying socket. - pub fn disconnect(&self, - reason: Option<DisconnectCode>, - description: &str, - lang: Option<&str>) -> Result<(), Error> { + pub fn disconnect( + &self, + reason: Option<DisconnectCode>, + description: &str, + lang: Option<&str>, + ) -> Result<(), Error> { let reason = reason.unwrap_or(ByApplication) as c_int; let description = try!(CString::new(description)); let lang = try!(CString::new(lang.unwrap_or(""))); unsafe { - self.rc(raw::libssh2_session_disconnect_ex(self.raw, - reason, - description.as_ptr(), - lang.as_ptr())) + self.rc(raw::libssh2_session_disconnect_ex( + self.raw, + reason, + description.as_ptr(), + lang.as_ptr(), + )) } } @@ -663,7 +709,9 @@ impl Binding for Session { unsafe fn from_raw(raw: *mut raw::LIBSSH2_SESSION) -> Session { Session { raw: raw } } - fn raw(&self) -> *mut raw::LIBSSH2_SESSION { self.raw } + fn raw(&self) -> *mut raw::LIBSSH2_SESSION { + self.raw + } } impl Drop for Session { @@ -676,9 +724,13 @@ impl Drop for Session { impl ScpFileStat { /// Returns the size of the remote file. - pub fn size(&self) -> u64 { self.stat.st_size as u64 } + pub fn size(&self) -> u64 { + self.stat.st_size as u64 + } /// Returns the listed mode of the remote file. - pub fn mode(&self) -> i32 { self.stat.st_mode as i32 } + pub fn mode(&self) -> i32 { + self.stat.st_mode as i32 + } /// Returns whether the remote file is a directory. pub fn is_dir(&self) -> bool { self.mode() & (libc::S_IFMT as i32) == (libc::S_IFDIR as i32) diff --git a/src/sftp.rs b/src/sftp.rs index 4e1eb56..a02c4db 100644 --- a/src/sftp.rs +++ b/src/sftp.rs @@ -1,12 +1,12 @@ +use libc::{c_int, c_long, c_uint, c_ulong, size_t}; use std::io::prelude::*; use std::io::{self, ErrorKind, SeekFrom}; use std::marker; use std::mem; use std::path::{Path, PathBuf}; -use libc::{c_int, c_ulong, c_long, c_uint, size_t}; -use {raw, Session, Error, Channel}; use util::{self, SessionBinding}; +use {raw, Channel, Error, Session}; /// A handle to a remote filesystem over SFTP. /// @@ -104,16 +104,23 @@ pub enum OpenType { impl<'sess> Sftp<'sess> { /// Open a handle to a file. - pub fn open_mode(&self, filename: &Path, flags: OpenFlags, - mode: i32, open_type: OpenType) -> Result<File, Error> { + pub fn open_mode( + &self, + filename: &Path, + flags: OpenFlags, + mode: i32, + open_type: OpenType, + ) -> Result<File, Error> { let filename = try!(util::path2bytes(filename)); unsafe { - let ret = raw::libssh2_sftp_open_ex(self.raw, - filename.as_ptr() as *const _, - filename.len() as c_uint, - flags.bits() as c_ulong, - mode as c_long, - open_type as c_int); + let ret = raw::libssh2_sftp_open_ex( + self.raw, + filename.as_ptr() as *const _, + filename.len() as c_uint, + flags.bits() as c_ulong, + mode as c_long, + open_type as c_int, + ); if ret.is_null() { Err(self.last_error()) } else { @@ -129,7 +136,12 @@ impl<'sess> Sftp<'sess> { /// Helper to create a file in write-only mode with truncation. pub fn create(&self, filename: &Path) -> Result<File, Error> { - self.open_mode(filename, OpenFlags::WRITE | OpenFlags::TRUNCATE, 0o644, OpenType::File) + self.open_mode( + filename, + OpenFlags::WRITE | OpenFlags::TRUNCATE, + 0o644, + OpenType::File, + ) } /// Helper to open a directory for reading its contents. @@ -141,15 +153,15 @@ impl<'sess> Sftp<'sess> { /// /// The returned paths are all joined with `dirname` when returned, and the /// paths `.` and `..` are filtered out of the returned list. - pub fn readdir(&self, dirname: &Path) - -> Result<Vec<(PathBuf, FileStat)>, Error> { + pub fn readdir(&self, dirname: &Path) -> Result<Vec<(PathBuf, FileStat)>, Error> { let mut dir = try!(self.opendir(dirname)); let mut ret = Vec::new(); loop { match dir.readdir() { Ok((filename, stat)) => { - if &*filename == Path::new(".") || - &*filename == Path::new("..") { continue } + if &*filename == Path::new(".") || &*filename == Path::new("..") { + continue; + } ret.push((dirname.join(&filename), stat)) } @@ -161,14 +173,15 @@ impl<'sess> Sftp<'sess> { } /// Create a directory on the remote file system. - pub fn mkdir(&self, filename: &Path, mode: i32) - -> Result<(), Error> { + pub fn mkdir(&self, filename: &Path, mode: i32) -> Result<(), Error> { let filename = try!(util::path2bytes(filename)); self.rc(unsafe { - raw::libssh2_sftp_mkdir_ex(self.raw, - filename.as_ptr() as *const _, - filename.len() as c_uint, - mode as c_long) + raw::libssh2_sftp_mkdir_ex( + self.raw, + filename.as_ptr() as *const _, + filename.len() as c_uint, + mode as c_long, + ) }) } @@ -176,9 +189,11 @@ impl<'sess> Sftp<'sess> { pub fn rmdir(&self, filename: &Path) -> Result<(), Error> { let filename = try!(util::path2bytes(filename)); self.rc(unsafe { - raw::libssh2_sftp_rmdir_ex(self.raw, - filename.as_ptr() as *const _, - filename.len() as c_uint) + raw::libssh2_sftp_rmdir_ex( + self.raw, + filename.as_ptr() as *const _, + filename.len() as c_uint, + ) }) } @@ -187,11 +202,13 @@ impl<'sess> Sftp<'sess> { let filename = try!(util::path2bytes(filename)); unsafe { let mut ret = mem::zeroed(); - let rc = raw::libssh2_sftp_stat_ex(self.raw, - filename.as_ptr() as *const _, - filename.len() as c_uint, - raw::LIBSSH2_SFTP_STAT, - &mut ret); + let rc = raw::libssh2_sftp_stat_ex( + self.raw, + filename.as_ptr() as *const _, + filename.len() as c_uint, + raw::LIBSSH2_SFTP_STAT, + &mut ret, + ); try!(self.rc(rc)); Ok(FileStat::from_raw(&ret)) } @@ -202,11 +219,13 @@ impl<'sess> Sftp<'sess> { let filename = try!(util::path2bytes(filename)); unsafe { let mut ret = mem::zeroed(); - let rc = raw::libssh2_sftp_stat_ex(self.raw, - filename.as_ptr() as *const _, - filename.len() as c_uint, - raw::LIBSSH2_SFTP_LSTAT, - &mut ret); + let rc = raw::libssh2_sftp_stat_ex( + self.raw, + filename.as_ptr() as *const _, + filename.len() as c_uint, + raw::LIBSSH2_SFTP_LSTAT, + &mut ret, + ); try!(self.rc(rc)); Ok(FileStat::from_raw(&ret)) } @@ -217,11 +236,13 @@ impl<'sess> Sftp<'sess> { let filename = try!(util::path2bytes(filename)); self.rc(unsafe { let mut raw = stat.raw(); - raw::libssh2_sftp_stat_ex(self.raw, - filename.as_ptr() as *const _, - filename.len() as c_uint, - raw::LIBSSH2_SFTP_SETSTAT, - &mut raw) + raw::libssh2_sftp_stat_ex( + self.raw, + filename.as_ptr() as *const _, + filename.len() as c_uint, + raw::LIBSSH2_SFTP_SETSTAT, + &mut raw, + ) }) } @@ -230,12 +251,14 @@ impl<'sess> Sftp<'sess> { let path = try!(util::path2bytes(path)); let target = try!(util::path2bytes(target)); self.rc(unsafe { - raw::libssh2_sftp_symlink_ex(self.raw, - path.as_ptr() as *const _, - path.len() as c_uint, - target.as_ptr() as *mut _, - target.len() as c_uint, - raw::LIBSSH2_SFTP_SYMLINK) + raw::libssh2_sftp_symlink_ex( + self.raw, + path.as_ptr() as *const _, + path.len() as c_uint, + target.as_ptr() as *mut _, + target.len() as c_uint, + raw::LIBSSH2_SFTP_SYMLINK, + ) }) } @@ -255,18 +278,20 @@ impl<'sess> Sftp<'sess> { let mut rc; loop { rc = unsafe { - raw::libssh2_sftp_symlink_ex(self.raw, - path.as_ptr() as *const _, - path.len() as c_uint, - ret.as_ptr() as *mut _, - ret.capacity() as c_uint, - op) + raw::libssh2_sftp_symlink_ex( + self.raw, + path.as_ptr() as *const _, + path.len() as c_uint, + ret.as_ptr() as *mut _, + ret.capacity() as c_uint, + op, + ) }; if rc == raw::LIBSSH2_ERROR_BUFFER_TOO_SMALL { let cap = ret.capacity(); ret.reserve(cap); } else { - break + break; } } if rc < 0 { @@ -289,20 +314,20 @@ impl<'sess> Sftp<'sess> { /// operation and/or using native system calls when possible. /// /// If no flags are specified then all flags are used. - pub fn rename(&self, src: &Path, dst: &Path, flags: Option<RenameFlags>) - -> Result<(), Error> { - let flags = flags.unwrap_or( - RenameFlags::ATOMIC | RenameFlags::OVERWRITE | RenameFlags::NATIVE - ); + pub fn rename(&self, src: &Path, dst: &Path, flags: Option<RenameFlags>) -> Result<(), Error> { + let flags = + flags.unwrap_or(RenameFlags::ATOMIC | RenameFlags::OVERWRITE | RenameFlags::NATIVE); let src = try!(util::path2bytes(src)); let dst = try!(util::path2bytes(dst)); self.rc(unsafe { - raw::libssh2_sftp_rename_ex(self.raw, - src.as_ptr() as *const _, - src.len() as c_uint, - dst.as_ptr() as *const _, - dst.len() as c_uint, - flags.bits()) + raw::libssh2_sftp_rename_ex( + self.raw, + src.as_ptr() as *const _, + src.len() as c_uint, + dst.as_ptr() as *const _, + dst.len() as c_uint, + flags.bits(), + ) }) } @@ -310,9 +335,7 @@ impl<'sess> Sftp<'sess> { pub fn unlink(&self, file: &Path) -> Result<(), Error> { let file = try!(util::path2bytes(file)); self.rc(unsafe { - raw::libssh2_sftp_unlink_ex(self.raw, - file.as_ptr() as *const _, - file.len() as c_uint) + raw::libssh2_sftp_unlink_ex(self.raw, file.as_ptr() as *const _, file.len() as c_uint) }) } @@ -324,21 +347,28 @@ impl<'sess> Sftp<'sess> { /// Translates a return code into a Rust-`Result` pub fn rc(&self, rc: c_int) -> Result<(), Error> { - if rc == 0 {Ok(())} else {Err(self.last_error())} + if rc == 0 { + Ok(()) + } else { + Err(self.last_error()) + } } } impl<'sess> SessionBinding<'sess> for Sftp<'sess> { type Raw = raw::LIBSSH2_SFTP; - unsafe fn from_raw(_sess: &'sess Session, - raw: *mut raw::LIBSSH2_SFTP) -> Sftp<'sess> { - Sftp { raw: raw, _marker: marker::PhantomData } + unsafe fn from_raw(_sess: &'sess Session, raw: *mut raw::LIBSSH2_SFTP) -> Sftp<'sess> { + Sftp { + raw: raw, + _marker: marker::PhantomData, + } + } + fn raw(&self) -> *mut raw::LIBSSH2_SFTP { + self.raw } - fn raw(&self) -> *mut raw::LIBSSH2_SFTP { self.raw } } - impl<'sess> Drop for Sftp<'sess> { fn drop(&mut self) { unsafe { assert_eq!(raw::libssh2_sftp_shutdown(self.raw), 0) } @@ -350,8 +380,10 @@ impl<'sftp> File<'sftp> { /// given session. /// /// This consumes ownership of `raw`. - unsafe fn from_raw(sftp: &'sftp Sftp<'sftp>, - raw: *mut raw::LIBSSH2_SFTP_HANDLE) -> File<'sftp> { + unsafe fn from_raw( + sftp: &'sftp Sftp<'sftp>, + raw: *mut raw::LIBSSH2_SFTP_HANDLE, + ) -> File<'sftp> { File { raw: raw, sftp: sftp, @@ -370,7 +402,9 @@ impl<'sftp> File<'sftp> { pub fn stat(&mut self) -> Result<FileStat, Error> { unsafe { let mut ret = mem::zeroed(); - try!(self.sftp.rc(raw::libssh2_sftp_fstat_ex(self.raw, &mut ret, 0))); + try!(self + .sftp + .rc(raw::libssh2_sftp_fstat_ex(self.raw, &mut ret, 0))); Ok(FileStat::from_raw(&ret)) } } @@ -400,25 +434,30 @@ impl<'sftp> File<'sftp> { let mut rc; loop { rc = unsafe { - raw::libssh2_sftp_readdir_ex(self.raw, - buf.as_mut_ptr() as *mut _, - buf.capacity() as size_t, - 0 as *mut _, 0, - &mut stat) + raw::libssh2_sftp_readdir_ex( + self.raw, + buf.as_mut_ptr() as *mut _, + buf.capacity() as size_t, + 0 as *mut _, + 0, + &mut stat, + ) }; if rc == raw::LIBSSH2_ERROR_BUFFER_TOO_SMALL { let cap = buf.capacity(); buf.reserve(cap); } else { - break + break; } } if rc < 0 { - return Err(self.sftp.last_error()) + return Err(self.sftp.last_error()); } else if rc == 0 { - return Err(Error::new(raw::LIBSSH2_ERROR_FILE, "no more files")) + return Err(Error::new(raw::LIBSSH2_ERROR_FILE, "no more files")); } else { - unsafe { buf.set_len(rc as usize); } + unsafe { + buf.set_len(rc as usize); + } } Ok((mkpath(buf), FileStat::from_raw(&stat))) } @@ -435,13 +474,11 @@ impl<'sftp> File<'sftp> { impl<'sftp> Read for File<'sftp> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { unsafe { - let rc = raw::libssh2_sftp_read(self.raw, - buf.as_mut_ptr() as *mut _, - buf.len() as size_t); + let rc = + raw::libssh2_sftp_read(self.raw, buf.as_mut_ptr() as *mut _, buf.len() as size_t); match rc { - n if n < 0 => Err(io::Error::new(ErrorKind::Other, - self.sftp.last_error())), - n => Ok(n as usize) + n if n < 0 => Err(io::Error::new(ErrorKind::Other, self.sftp.last_error())), + n => Ok(n as usize), } } } @@ -450,9 +487,7 @@ impl<'sftp> Read for File<'sftp> { impl<'sftp> Write for File<'sftp> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { let rc = unsafe { - raw::libssh2_sftp_write(self.raw, - buf.as_ptr() as *const _, - buf.len() as size_t) + raw::libssh2_sftp_write(self.raw, buf.as_ptr() as *const _, buf.len() as size_t) }; if rc < 0 { Err(io::Error::new(ErrorKind::Other, self.sftp.last_error())) @@ -460,7 +495,9 @@ impl<'sftp> Write for File<'sftp> { Ok(rc as usize) } } - fn flush(&mut self) -> io::Result<()> { Ok(()) } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } } impl<'sftp> Seek for File<'sftp> { @@ -484,15 +521,10 @@ impl<'sftp> Seek for File<'sftp> { SeekFrom::End(offset) => match self.stat() { Ok(s) => match s.size { Some(size) => (size as i64 + offset) as u64, - None => { - return Err(io::Error::new(ErrorKind::Other, - "no file size available")) - } + None => return Err(io::Error::new(ErrorKind::Other, "no file size available")), }, - Err(e) => { - return Err(io::Error::new(ErrorKind::Other, e)) - } - } + Err(e) => return Err(io::Error::new(ErrorKind::Other, e)), + }, }; unsafe { raw::libssh2_sftp_seek64(self.raw, next) } Ok(next) @@ -508,50 +540,58 @@ impl<'sftp> Drop for File<'sftp> { impl FileStat { /// Returns the file type for this filestat. pub fn file_type(&self) -> FileType { - FileType { perm: self.perm.unwrap_or(0) as c_ulong } + FileType { + perm: self.perm.unwrap_or(0) as c_ulong, + } } /// Returns whether this metadata is for a directory. - pub fn is_dir(&self) -> bool { self.file_type().is_dir() } + pub fn is_dir(&self) -> bool { + self.file_type().is_dir() + } /// Returns whether this metadata is for a regular file. - pub fn is_file(&self) -> bool { self.file_type().is_file() } + pub fn is_file(&self) -> bool { + self.file_type().is_file() + } /// Creates a new instance of a stat from a raw instance. pub fn from_raw(raw: &raw::LIBSSH2_SFTP_ATTRIBUTES) -> FileStat { - fn val<T: Copy>(raw: &raw::LIBSSH2_SFTP_ATTRIBUTES, t: &T, - flag: c_ulong) -> Option<T> { - if raw.flags & flag != 0 {Some(*t)} else {None} + fn val<T: Copy>(raw: &raw::LIBSSH2_SFTP_ATTRIBUTES, t: &T, flag: c_ulong) -> Option<T> { + if raw.flags & flag != 0 { + Some(*t) + } else { + None + } } FileStat { size: val(raw, &raw.filesize, raw::LIBSSH2_SFTP_ATTR_SIZE), - uid: val(raw, &raw.uid, raw::LIBSSH2_SFTP_ATTR_UIDGID) - .map(|s| s as u32), - gid: val(raw, &raw.gid, raw::LIBSSH2_SFTP_ATTR_UIDGID) - .map(|s| s as u32), - perm: val(raw, &raw.permissions, raw::LIBSSH2_SFTP_ATTR_PERMISSIONS) - .map(|s| s as u32), - mtime: val(raw, &raw.mtime, raw::LIBSSH2_SFTP_ATTR_ACMODTIME) - .map(|s| s as u64), - atime: val(raw, &raw.atime, raw::LIBSSH2_SFTP_ATTR_ACMODTIME) - .map(|s| s as u64), + uid: val(raw, &raw.uid, raw::LIBSSH2_SFTP_ATTR_UIDGID).map(|s| s as u32), + gid: val(raw, &raw.gid, raw::LIBSSH2_SFTP_ATTR_UIDGID).map(|s| s as u32), + perm: val(raw, &raw.permissions, raw::LIBSSH2_SFTP_ATTR_PERMISSIONS).map(|s| s as u32), + mtime: val(raw, &raw.mtime, raw::LIBSSH2_SFTP_ATTR_ACMODTIME).map(|s| s as u64), + atime: val(raw, &raw.atime, raw::LIBSSH2_SFTP_ATTR_ACMODTIME).map(|s| s as u64), } } /// Convert this stat structure to its raw representation. pub fn raw(&self) -> raw::LIBSSH2_SFTP_ATTRIBUTES { fn flag<T>(o: &Option<T>, flag: c_ulong) -> c_ulong { - if o.is_some() {flag} else {0} + if o.is_some() { + flag + } else { + 0 + } } raw::LIBSSH2_SFTP_ATTRIBUTES { - flags: flag(&self.size, raw::LIBSSH2_SFTP_ATTR_SIZE) | - flag(&self.uid, raw::LIBSSH2_SFTP_ATTR_UIDGID) | - flag(&self.gid, raw::LIBSSH2_SFTP_ATTR_UIDGID) | - flag(&self.perm, raw::LIBSSH2_SFTP_ATTR_PERMISSIONS) | - flag(&self.atime, raw::LIBSSH2_SFTP_ATTR_ACMODTIME) | - flag(&self.mtime, raw::LIBSSH2_SFTP_ATTR_ACMODTIME), + flags: flag(&self.size, raw::LIBSSH2_SFTP_ATTR_SIZE) + | flag(&self.uid, raw::LIBSSH2_SFTP_ATTR_UIDGID) + | flag(&self.gid, raw::LIBSSH2_SFTP_ATTR_UIDGID) + | flag(&self.perm, raw::LIBSSH2_SFTP_ATTR_PERMISSIONS) + | flag(&self.atime, raw::LIBSSH2_SFTP_ATTR_ACMODTIME) + | flag(&self.mtime, raw::LIBSSH2_SFTP_ATTR_ACMODTIME), filesize: self.size.unwrap_or(0), uid: self.uid.unwrap_or(0) as c_ulong, gid: self.gid.unwrap_or(0) as c_ulong, @@ -564,13 +604,19 @@ impl FileStat { impl FileType { /// Test whether this file type represents a directory. - pub fn is_dir(&self) -> bool { self.is(raw::LIBSSH2_SFTP_S_IFDIR) } + pub fn is_dir(&self) -> bool { + self.is(raw::LIBSSH2_SFTP_S_IFDIR) + } /// Test whether this file type represents a regular file. - pub fn is_file(&self) -> bool { self.is(raw::LIBSSH2_SFTP_S_IFREG) } + pub fn is_file(&self) -> bool { + self.is(raw::LIBSSH2_SFTP_S_IFREG) + } /// Test whether this file type represents a symbolic link. - pub fn is_symlink(&self) -> bool { self.is(raw::LIBSSH2_SFTP_S_IFLNK) } + pub fn is_symlink(&self) -> bool { + self.is(raw::LIBSSH2_SFTP_S_IFLNK) + } fn is(&self, perm: c_ulong) -> bool { (self.perm & raw::LIBSSH2_SFTP_S_IFMT) == perm @@ -579,8 +625,8 @@ impl FileType { #[cfg(unix)] fn mkpath(v: Vec<u8>) -> PathBuf { - use std::os::unix::prelude::*; use std::ffi::OsStr; + use std::os::unix::prelude::*; PathBuf::from(OsStr::from_bytes(&v)) } #[cfg(windows)] diff --git a/src/util.rs b/src/util.rs index 414bbb2..ac6c722 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use std::path::Path; -use {raw, Session, Error}; +use {raw, Error, Session}; #[doc(hidden)] pub trait Binding: Sized { @@ -18,8 +18,7 @@ pub trait SessionBinding<'sess>: Sized { unsafe fn from_raw(sess: &'sess Session, raw: *mut Self::Raw) -> Self; fn raw(&self) -> *mut Self::Raw; - unsafe fn from_raw_opt(sess: &'sess Session, raw: *mut Self::Raw) - -> Result<Self, Error> { + unsafe fn from_raw_opt(sess: &'sess Session, raw: *mut Self::Raw) -> Result<Self, Error> { if raw.is_null() { Err(Error::last_error(sess).unwrap_or_else(Error::unknown)) } else { @@ -30,8 +29,8 @@ pub trait SessionBinding<'sess>: Sized { #[cfg(unix)] pub fn path2bytes(p: &Path) -> Result<Cow<[u8]>, Error> { - use std::os::unix::prelude::*; use std::ffi::OsStr; + use std::os::unix::prelude::*; let s: &OsStr = p.as_ref(); check(Cow::Borrowed(s.as_bytes())) } @@ -39,8 +38,12 @@ pub fn path2bytes(p: &Path) -> Result<Cow<[u8]>, Error> { pub fn path2bytes(p: &Path) -> Result<Cow<[u8]>, Error> { p.to_str() .map(|s| s.as_bytes()) - .ok_or_else(|| Error::new(raw::LIBSSH2_ERROR_INVAL, - "only unicode paths on windows may be used")) + .ok_or_else(|| { + Error::new( + raw::LIBSSH2_ERROR_INVAL, + "only unicode paths on windows may be used", + ) + }) .map(|bytes| { if bytes.contains(&b'\\') { // Normalize to Unix-style path separators @@ -60,8 +63,10 @@ pub fn path2bytes(p: &Path) -> Result<Cow<[u8]>, Error> { fn check(b: Cow<[u8]>) -> Result<Cow<[u8]>, Error> { if b.iter().any(|b| *b == 0) { - Err(Error::new(raw::LIBSSH2_ERROR_INVAL, - "path provided contains a 0 byte")) + Err(Error::new( + raw::LIBSSH2_ERROR_INVAL, + "path provided contains a 0 byte", + )) } else { Ok(b) } |