diff --git a/src/Renci.SshNet.Silverlight/Renci.SshNet.Silverlight.csproj b/src/Renci.SshNet.Silverlight/Renci.SshNet.Silverlight.csproj index beeef21a0..7505a175a 100644 --- a/src/Renci.SshNet.Silverlight/Renci.SshNet.Silverlight.csproj +++ b/src/Renci.SshNet.Silverlight/Renci.SshNet.Silverlight.csproj @@ -1358,6 +1358,9 @@ Sftp\SftpFile.cs + + Sftp\ISftpFile.cs + Sftp\SftpFileAttributes.cs diff --git a/src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj b/src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj index 93b950edc..cff69e1cd 100644 --- a/src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj +++ b/src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj @@ -1364,6 +1364,9 @@ Sftp\SftpFile.cs + + Sftp\ISftpFile.cs + Sftp\SftpFileAttributes.cs diff --git a/src/Renci.SshNet.Tests/Classes/SftpClientTest.cs b/src/Renci.SshNet.Tests/Classes/SftpClientTest.cs index f562f66bb..8f84546bf 100644 --- a/src/Renci.SshNet.Tests/Classes/SftpClientTest.cs +++ b/src/Renci.SshNet.Tests/Classes/SftpClientTest.cs @@ -562,8 +562,8 @@ public void EndListDirectoryTest() ConnectionInfo connectionInfo = null; // TODO: Initialize to an appropriate value SftpClient target = new SftpClient(connectionInfo); // TODO: Initialize to an appropriate value IAsyncResult asyncResult = null; // TODO: Initialize to an appropriate value - IEnumerable expected = null; // TODO: Initialize to an appropriate value - IEnumerable actual; + IEnumerable expected = null; // TODO: Initialize to an appropriate value + IEnumerable actual; actual = target.EndListDirectory(asyncResult); Assert.AreEqual(expected, actual); Assert.Inconclusive("Verify the correctness of this test method."); @@ -702,8 +702,8 @@ public void GetTest() ConnectionInfo connectionInfo = null; // TODO: Initialize to an appropriate value SftpClient target = new SftpClient(connectionInfo); // TODO: Initialize to an appropriate value string path = string.Empty; // TODO: Initialize to an appropriate value - SftpFile expected = null; // TODO: Initialize to an appropriate value - SftpFile actual; + ISftpFile expected = null; // TODO: Initialize to an appropriate value + ISftpFile actual; actual = target.Get(path); Assert.AreEqual(expected, actual); Assert.Inconclusive("Verify the correctness of this test method."); @@ -802,8 +802,8 @@ public void ListDirectoryTest() SftpClient target = new SftpClient(connectionInfo); // TODO: Initialize to an appropriate value string path = string.Empty; // TODO: Initialize to an appropriate value Action listCallback = null; // TODO: Initialize to an appropriate value - IEnumerable expected = null; // TODO: Initialize to an appropriate value - IEnumerable actual; + IEnumerable expected = null; // TODO: Initialize to an appropriate value + IEnumerable actual; actual = target.ListDirectory(path, listCallback); Assert.AreEqual(expected, actual); Assert.Inconclusive("Verify the correctness of this test method."); diff --git a/src/Renci.SshNet.UAP10/Renci.SshNet.UAP10.csproj b/src/Renci.SshNet.UAP10/Renci.SshNet.UAP10.csproj index d0eb423a2..a1f0c994f 100644 --- a/src/Renci.SshNet.UAP10/Renci.SshNet.UAP10.csproj +++ b/src/Renci.SshNet.UAP10/Renci.SshNet.UAP10.csproj @@ -1440,6 +1440,9 @@ Sftp\SftpFile.cs + + Sftp\ISftpFile.cs + Sftp\SftpFileAttributes.cs diff --git a/src/Renci.SshNet.WindowsPhone/Renci.SshNet.WindowsPhone.csproj b/src/Renci.SshNet.WindowsPhone/Renci.SshNet.WindowsPhone.csproj index 317dbc845..f8342e11b 100644 --- a/src/Renci.SshNet.WindowsPhone/Renci.SshNet.WindowsPhone.csproj +++ b/src/Renci.SshNet.WindowsPhone/Renci.SshNet.WindowsPhone.csproj @@ -1343,6 +1343,9 @@ Sftp\SftpFile.cs + + Sftp\ISftpFile.cs + Sftp\SftpFileAttributes.cs diff --git a/src/Renci.SshNet.WindowsPhone8/Renci.SshNet.WindowsPhone8.csproj b/src/Renci.SshNet.WindowsPhone8/Renci.SshNet.WindowsPhone8.csproj index f34c1d8e8..fb301e597 100644 --- a/src/Renci.SshNet.WindowsPhone8/Renci.SshNet.WindowsPhone8.csproj +++ b/src/Renci.SshNet.WindowsPhone8/Renci.SshNet.WindowsPhone8.csproj @@ -1396,6 +1396,9 @@ Sftp\SftpFile.cs + + Sftp\ISftpFile.cs + Sftp\SftpFileAttributes.cs diff --git a/src/Renci.SshNet/ISftpClient.cs b/src/Renci.SshNet/ISftpClient.cs index b1212cfea..62f432491 100644 --- a/src/Renci.SshNet/ISftpClient.cs +++ b/src/Renci.SshNet/ISftpClient.cs @@ -10,7 +10,7 @@ namespace Renci.SshNet /// /// Implementation of the SSH File Transfer Protocol (SFTP) over SSH. /// - public interface ISftpClient + public interface ISftpClient : IDisposable { /// /// Gets or sets the maximum size of the buffer in bytes. @@ -525,7 +525,7 @@ public interface ISftpClient /// A list of files. /// /// The object did not come from the corresponding async method on this type.-or- was called multiple times with the same . - IEnumerable EndListDirectory(IAsyncResult asyncResult); + IEnumerable EndListDirectory(IAsyncResult asyncResult); /// /// Ends the synchronize directories. @@ -568,13 +568,13 @@ public interface ISftpClient /// /// The path. /// - /// A reference to file object. + /// A reference to file object. /// /// Client is not connected. /// was not found on the remote host. /// is null. /// The method was called after the client was disposed. - SftpFile Get(string path); + ISftpFile Get(string path); /// /// Gets the of the file on the path. @@ -666,7 +666,7 @@ public interface ISftpClient /// Permission to list the contents of the directory was denied by the remote host. -or- A SSH command was denied by the server. /// A SSH error where is the message from the remote host. /// The method was called after the client was disposed. - IEnumerable ListDirectory(string path, Action listCallback = null); + IEnumerable ListDirectory(string path, Action listCallback = null); /// /// Opens a on the specified path with read/write access. diff --git a/src/Renci.SshNet/Sftp/ISftpFile.cs b/src/Renci.SshNet/Sftp/ISftpFile.cs new file mode 100644 index 000000000..60c4a7a52 --- /dev/null +++ b/src/Renci.SshNet/Sftp/ISftpFile.cs @@ -0,0 +1,233 @@ +using System; + +namespace Renci.SshNet.Sftp +{ + /// + /// Represents SFTP file information + /// + public interface ISftpFile + { + /// + /// Gets the file attributes. + /// + SftpFileAttributes Attributes { get; } + + /// + /// Gets the full path of the directory or file. + /// + string FullName { get; } + + /// + /// For files, gets the name of the file. For directories, gets the name of the last directory in the hierarchy if a hierarchy exists. + /// Otherwise, the Name property gets the name of the directory. + /// + string Name { get; } + + /// + /// Gets or sets the time the current file or directory was last accessed. + /// + /// + /// The time that the current file or directory was last accessed. + /// + DateTime LastAccessTime { get; set; } + + /// + /// Gets or sets the time when the current file or directory was last written to. + /// + /// + /// The time the current file was last written. + /// + DateTime LastWriteTime { get; set; } + + /// + /// Gets or sets the time, in coordinated universal time (UTC), the current file or directory was last accessed. + /// + /// + /// The time that the current file or directory was last accessed. + /// + DateTime LastAccessTimeUtc { get; set; } + + /// + /// Gets or sets the time, in coordinated universal time (UTC), when the current file or directory was last written to. + /// + /// + /// The time the current file was last written. + /// + DateTime LastWriteTimeUtc { get; set; } + + /// + /// Gets or sets the size, in bytes, of the current file. + /// + /// + /// The size of the current file in bytes. + /// + long Length { get; } + + /// + /// Gets or sets file user id. + /// + /// + /// File user id. + /// + int UserId { get; set; } + + /// + /// Gets or sets file group id. + /// + /// + /// File group id. + /// + int GroupId { get; set; } + + /// + /// Gets a value indicating whether file represents a socket. + /// + /// + /// true if file represents a socket; otherwise, false. + /// + bool IsSocket { get; } + + /// + /// Gets a value indicating whether file represents a symbolic link. + /// + /// + /// true if file represents a symbolic link; otherwise, false. + /// + bool IsSymbolicLink { get; } + + /// + /// Gets a value indicating whether file represents a regular file. + /// + /// + /// true if file represents a regular file; otherwise, false. + /// + bool IsRegularFile { get; } + + /// + /// Gets a value indicating whether file represents a block device. + /// + /// + /// true if file represents a block device; otherwise, false. + /// + bool IsBlockDevice { get; } + + /// + /// Gets a value indicating whether file represents a directory. + /// + /// + /// true if file represents a directory; otherwise, false. + /// + bool IsDirectory { get; } + + /// + /// Gets a value indicating whether file represents a character device. + /// + /// + /// true if file represents a character device; otherwise, false. + /// + bool IsCharacterDevice { get; } + + /// + /// Gets a value indicating whether file represents a named pipe. + /// + /// + /// true if file represents a named pipe; otherwise, false. + /// + bool IsNamedPipe { get; } + + /// + /// Gets or sets a value indicating whether the owner can read from this file. + /// + /// + /// true if owner can read from this file; otherwise, false. + /// + bool OwnerCanRead { get; set; } + + /// + /// Gets or sets a value indicating whether the owner can write into this file. + /// + /// + /// true if owner can write into this file; otherwise, false. + /// + bool OwnerCanWrite { get; set; } + + /// + /// Gets or sets a value indicating whether the owner can execute this file. + /// + /// + /// true if owner can execute this file; otherwise, false. + /// + bool OwnerCanExecute { get; set; } + + /// + /// Gets or sets a value indicating whether the group members can read from this file. + /// + /// + /// true if group members can read from this file; otherwise, false. + /// + bool GroupCanRead { get; set; } + + /// + /// Gets or sets a value indicating whether the group members can write into this file. + /// + /// + /// true if group members can write into this file; otherwise, false. + /// + bool GroupCanWrite { get; set; } + + /// + /// Gets or sets a value indicating whether the group members can execute this file. + /// + /// + /// true if group members can execute this file; otherwise, false. + /// + bool GroupCanExecute { get; set; } + + /// + /// Gets or sets a value indicating whether the others can read from this file. + /// + /// + /// true if others can read from this file; otherwise, false. + /// + bool OthersCanRead { get; set; } + + /// + /// Gets or sets a value indicating whether the others can write into this file. + /// + /// + /// true if others can write into this file; otherwise, false. + /// + bool OthersCanWrite { get; set; } + + /// + /// Gets or sets a value indicating whether the others can execute this file. + /// + /// + /// true if others can execute this file; otherwise, false. + /// + bool OthersCanExecute { get; set; } + + /// + /// Sets file permissions. + /// + /// The mode. + void SetPermissions(short mode); + + /// + /// Permanently deletes a file on remote machine. + /// + void Delete(); + + /// + /// Moves a specified file to a new location on remote machine, providing the option to specify a new file name. + /// + /// The path to move the file to, which can specify a different file name. + /// is null. + void MoveTo(string destFileName); + + /// + /// Updates file status on the server. + /// + void UpdateStatus(); + } +} \ No newline at end of file diff --git a/src/Renci.SshNet/Sftp/SftpFile.cs b/src/Renci.SshNet/Sftp/SftpFile.cs index cfcc37a2f..6356d26ce 100644 --- a/src/Renci.SshNet/Sftp/SftpFile.cs +++ b/src/Renci.SshNet/Sftp/SftpFile.cs @@ -7,7 +7,7 @@ namespace Renci.SshNet.Sftp /// /// Represents SFTP file information /// - public class SftpFile + public sealed class SftpFile : ISftpFile { private readonly ISftpSession _sftpSession; diff --git a/src/Renci.SshNet/Sftp/SftpListDirectoryAsyncResult.cs b/src/Renci.SshNet/Sftp/SftpListDirectoryAsyncResult.cs index cb7b60132..2b791e54c 100644 --- a/src/Renci.SshNet/Sftp/SftpListDirectoryAsyncResult.cs +++ b/src/Renci.SshNet/Sftp/SftpListDirectoryAsyncResult.cs @@ -7,7 +7,7 @@ namespace Renci.SshNet.Sftp /// /// Encapsulates the results of an asynchronous directory list operation. /// - public class SftpListDirectoryAsyncResult : AsyncResult> + public class SftpListDirectoryAsyncResult : AsyncResult> { /// /// Gets the number of files read so far. diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index 3c22290d0..d0cb449d6 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -469,7 +469,7 @@ public void SymbolicLink(string path, string linkPath) /// Permission to list the contents of the directory was denied by the remote host. -or- A SSH command was denied by the server. /// A SSH error where is the message from the remote host. /// The method was called after the client was disposed. - public IEnumerable ListDirectory(string path, Action listCallback = null) + public IEnumerable ListDirectory(string path, Action listCallback = null) { CheckDisposed(); @@ -526,7 +526,7 @@ public IAsyncResult BeginListDirectory(string path, AsyncCallback asyncCallback, /// A list of files. /// /// The object did not come from the corresponding async method on this type.-or- was called multiple times with the same . - public IEnumerable EndListDirectory(IAsyncResult asyncResult) + public IEnumerable EndListDirectory(IAsyncResult asyncResult) { var ar = asyncResult as SftpListDirectoryAsyncResult; @@ -542,13 +542,13 @@ public IEnumerable EndListDirectory(IAsyncResult asyncResult) /// /// The path. /// - /// A reference to file object. + /// A reference to file object. /// /// Client is not connected. /// was not found on the remote host. /// is null. /// The method was called after the client was disposed. - public SftpFile Get(string path) + public ISftpFile Get(string path) { CheckDisposed(); @@ -1920,7 +1920,7 @@ private IEnumerable InternalSynchronizeDirectories(string sourcePath, #region Existing Files at The Destination var destFiles = InternalListDirectory(destinationPath, null); - var destDict = new Dictionary(); + var destDict = new Dictionary(); foreach (var destFile in destFiles) { if (destFile.IsDirectory) @@ -1986,7 +1986,7 @@ private IEnumerable InternalSynchronizeDirectories(string sourcePath, /// /// is null. /// Client not connected. - private IEnumerable InternalListDirectory(string path, Action listCallback) + private IEnumerable InternalListDirectory(string path, Action listCallback) { if (path == null) throw new ArgumentNullException("path"); @@ -2003,14 +2003,19 @@ private IEnumerable InternalListDirectory(string path, Action lis if (!basePath.EndsWith("/")) basePath = string.Format("{0}/", fullPath); - var result = new List(); + var result = new List(); var files = _sftpSession.RequestReadDir(handle); while (files != null) { - result.AddRange(from f in files - select new SftpFile(_sftpSession, string.Format(CultureInfo.InvariantCulture, "{0}{1}", basePath, f.Key), f.Value)); + foreach (var f in files) + { + result.Add(new SftpFile( + _sftpSession, + string.Format(CultureInfo.InvariantCulture, "{0}{1}", basePath, f.Key), + f.Value)); + } // Call callback to report number of files read if (listCallback != null)