mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-10-18 06:21:30 +08:00
Refactor SftpFileAttributes class to be public
Add SetAttributes and GetAttributes methods
This commit is contained in:
@@ -131,7 +131,6 @@
|
||||
<Compile Include="Sftp\CloseCommand.cs" />
|
||||
<Compile Include="Sftp\OpenCommand.cs" />
|
||||
<Compile Include="Sftp\ReadCommand.cs" />
|
||||
<Compile Include="Sftp\SetFileStatusCommand.cs" />
|
||||
<Compile Include="Sftp\SetStatusCommand.cs" />
|
||||
<Compile Include="Sftp\SftpFileAttributes.cs" />
|
||||
<Compile Include="Sftp\SftpFileStream.cs" />
|
||||
@@ -187,7 +186,6 @@
|
||||
<Compile Include="Security\CipherTripleDES.cs" />
|
||||
<Compile Include="Compression\Compressor.cs" />
|
||||
<Compile Include="Sftp\Messages\AceMasks.cs" />
|
||||
<Compile Include="Sftp\Messages\Attributes.cs" />
|
||||
<Compile Include="Sftp\Messages\AttributesMessage.cs" />
|
||||
<Compile Include="Sftp\Messages\CloseMessage.cs" />
|
||||
<Compile Include="Sftp\Messages\DataMessage.cs" />
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Renci.SshNet.Sftp.Messages
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents SFTP File attribute.
|
||||
/// </summary>
|
||||
public class SftpFileAttributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the size.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The size.
|
||||
/// </value>
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user id.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The user id.
|
||||
/// </value>
|
||||
public uint? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the group id.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The group id.
|
||||
/// </value>
|
||||
public uint? GroupId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the permissions.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The permissions.
|
||||
/// </value>
|
||||
public uint Permissions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the access time.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The access time.
|
||||
/// </value>
|
||||
public DateTime? AccessTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the modify time.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The modify time.
|
||||
/// </value>
|
||||
public DateTime? ModifyTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the extensions.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The extensions.
|
||||
/// </value>
|
||||
public IDictionary<string, string> Extensions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -13,14 +13,14 @@
|
||||
|
||||
public MkDirMessage()
|
||||
{
|
||||
this.Attributes = new SftpFileAttributes();
|
||||
this.Attributes = SftpFileAttributes.Empty;
|
||||
}
|
||||
|
||||
public MkDirMessage(uint requestId, string path)
|
||||
: base(requestId)
|
||||
{
|
||||
this.Path = path;
|
||||
this.Attributes = new SftpFileAttributes();
|
||||
this.Attributes = SftpFileAttributes.Empty;
|
||||
}
|
||||
|
||||
public MkDirMessage(uint requestId, string path, SftpFileAttributes attributes)
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Renci.SshNet.Sftp.Messages
|
||||
{
|
||||
this.Filename = fileName;
|
||||
this.Flags = flags;
|
||||
this.Attributes = new SftpFileAttributes();
|
||||
this.Attributes = SftpFileAttributes.Empty;
|
||||
}
|
||||
|
||||
public OpenMessage(uint requestId, string fileName, Flags flags, SftpFileAttributes attributes)
|
||||
|
||||
@@ -52,42 +52,48 @@ namespace Renci.SshNet.Sftp.Messages
|
||||
|
||||
protected SftpFileAttributes ReadAttributes()
|
||||
{
|
||||
var attributes = new SftpFileAttributes();
|
||||
|
||||
var flag = this.ReadUInt32();
|
||||
|
||||
long size = -1;
|
||||
int userId = -1;
|
||||
int groupId = -1;
|
||||
uint permissions = 0;
|
||||
var accessTime = DateTime.MinValue;
|
||||
var modifyTime = DateTime.MinValue;
|
||||
IDictionary<string, string> extensions = null;
|
||||
|
||||
if ((flag & 0x00000001) == 0x00000001) // SSH_FILEXFER_ATTR_SIZE
|
||||
{
|
||||
attributes.Size = this.ReadUInt64();
|
||||
|
||||
size = (long)this.ReadUInt64();
|
||||
}
|
||||
|
||||
if ((flag & 0x00000002) == 0x00000002) // SSH_FILEXFER_ATTR_UIDGID
|
||||
{
|
||||
attributes.UserId = this.ReadUInt32();
|
||||
userId = (int)this.ReadUInt32();
|
||||
|
||||
attributes.GroupId = this.ReadUInt32();
|
||||
groupId = (int)this.ReadUInt32();
|
||||
}
|
||||
|
||||
if ((flag & 0x00000004) == 0x00000004) // SSH_FILEXFER_ATTR_PERMISSIONS
|
||||
{
|
||||
attributes.Permissions = this.ReadUInt32();
|
||||
permissions = this.ReadUInt32();
|
||||
}
|
||||
|
||||
if ((flag & 0x00000008) == 0x00000008) // SSH_FILEXFER_ATTR_ACMODTIME
|
||||
{
|
||||
var time = this.ReadUInt32();
|
||||
attributes.AccessTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
|
||||
accessTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
|
||||
time = this.ReadUInt32();
|
||||
attributes.ModifyTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
|
||||
modifyTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
|
||||
}
|
||||
|
||||
if ((flag & 0x80000000) == 0x80000000) // SSH_FILEXFER_ATTR_ACMODTIME
|
||||
{
|
||||
var extendedCount = this.ReadUInt32();
|
||||
attributes.Extensions = this.ReadExtensionPair();
|
||||
extensions = this.ReadExtensionPair();
|
||||
}
|
||||
var attributes = new SftpFileAttributes(accessTime, modifyTime, size, userId, groupId, permissions, extensions);
|
||||
|
||||
return attributes;
|
||||
}
|
||||
@@ -103,12 +109,12 @@ namespace Renci.SshNet.Sftp.Messages
|
||||
{
|
||||
UInt32 flag = 0;
|
||||
|
||||
if (attributes.Size.HasValue)
|
||||
if (attributes.Size > -1)
|
||||
{
|
||||
flag |= 0x00000001;
|
||||
}
|
||||
|
||||
if (attributes.UserId.HasValue && attributes.GroupId.HasValue)
|
||||
if (attributes.UserId > -1 && attributes.GroupId > -1)
|
||||
{
|
||||
flag |= 0x00000002;
|
||||
}
|
||||
@@ -118,7 +124,7 @@ namespace Renci.SshNet.Sftp.Messages
|
||||
flag |= 0x00000004;
|
||||
}
|
||||
|
||||
if (attributes.AccessTime.HasValue && attributes.ModifyTime.HasValue)
|
||||
if (attributes.LastAccessTime > DateTime.MinValue && attributes.LastWriteTime > DateTime.MinValue)
|
||||
{
|
||||
flag |= 0x00000008;
|
||||
}
|
||||
@@ -130,15 +136,15 @@ namespace Renci.SshNet.Sftp.Messages
|
||||
|
||||
this.Write(flag);
|
||||
|
||||
if (attributes.Size.HasValue)
|
||||
if (attributes.Size > -1)
|
||||
{
|
||||
this.Write(attributes.Size.Value);
|
||||
this.Write((UInt64)attributes.Size);
|
||||
}
|
||||
|
||||
if (attributes.UserId.HasValue && attributes.GroupId.HasValue)
|
||||
if (attributes.UserId > -1 && attributes.GroupId > -1)
|
||||
{
|
||||
this.Write(attributes.UserId.Value);
|
||||
this.Write(attributes.GroupId.Value);
|
||||
this.Write((UInt32)attributes.UserId);
|
||||
this.Write((UInt32)attributes.GroupId);
|
||||
}
|
||||
|
||||
if (attributes.Permissions > 0)
|
||||
@@ -146,11 +152,11 @@ namespace Renci.SshNet.Sftp.Messages
|
||||
this.Write(attributes.Permissions);
|
||||
}
|
||||
|
||||
if (attributes.AccessTime.HasValue && attributes.ModifyTime.HasValue)
|
||||
if (attributes.LastAccessTime > DateTime.MinValue && attributes.LastWriteTime > DateTime.MinValue)
|
||||
{
|
||||
uint time = (uint)(attributes.AccessTime.Value.ToFileTime() / 10000000 - 11644473600);
|
||||
uint time = (uint)(attributes.LastAccessTime.ToFileTime() / 10000000 - 11644473600);
|
||||
this.Write(time);
|
||||
time = (uint)(attributes.ModifyTime.Value.ToFileTime() / 10000000 - 11644473600);
|
||||
time = (uint)(attributes.LastWriteTime.ToFileTime() / 10000000 - 11644473600);
|
||||
this.Write(time);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Renci.SshNet.Sftp.Messages;
|
||||
|
||||
namespace Renci.SshNet.Sftp
|
||||
{
|
||||
internal class SetFileStatusCommand : SftpCommand
|
||||
{
|
||||
private string _path;
|
||||
|
||||
private SftpFileAttributes _attributes;
|
||||
|
||||
public SftpFile SftpFile { get; private set; }
|
||||
|
||||
public SetFileStatusCommand(SftpSession sftpSession, string path, SftpFileAttributes attributes)
|
||||
: base(sftpSession)
|
||||
{
|
||||
this._path = path;
|
||||
|
||||
this._attributes = attributes;
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
this.SendSetStatMessage(this._path, this._attributes);
|
||||
}
|
||||
|
||||
protected override void OnStatus(StatusCodes statusCode, string errorMessage, string language)
|
||||
{
|
||||
base.OnStatus(statusCode, errorMessage, language);
|
||||
|
||||
if (statusCode == StatusCodes.Ok)
|
||||
{
|
||||
this.CompleteExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,57 +12,10 @@ namespace Renci.SshNet.Sftp
|
||||
/// </summary>
|
||||
public class SftpFile
|
||||
{
|
||||
#region Bitmask constats
|
||||
|
||||
private static UInt32 S_IFMT = 0xF000; // bitmask for the file type bitfields
|
||||
|
||||
private static UInt32 S_IFSOCK = 0xC000; // socket
|
||||
|
||||
private static UInt32 S_IFLNK = 0xA000; // symbolic link
|
||||
|
||||
private static UInt32 S_IFREG = 0x8000; // regular file
|
||||
|
||||
private static UInt32 S_IFBLK = 0x6000; // block device
|
||||
|
||||
private static UInt32 S_IFDIR = 0x4000; // directory
|
||||
|
||||
private static UInt32 S_IFCHR = 0x2000; // character device
|
||||
|
||||
private static UInt32 S_IFIFO = 0x1000; // FIFO
|
||||
|
||||
private static UInt32 S_ISUID = 0x0800; // set UID bit
|
||||
|
||||
private static UInt32 S_ISGID = 0x0400; // set-group-ID bit (see below)
|
||||
|
||||
private static UInt32 S_ISVTX = 0x0200; // sticky bit (see below)
|
||||
|
||||
private static UInt32 S_IRUSR = 0x0100; // owner has read permission
|
||||
|
||||
private static UInt32 S_IWUSR = 0x0080; // owner has write permission
|
||||
|
||||
private static UInt32 S_IXUSR = 0x0040; // owner has execute permission
|
||||
|
||||
private static UInt32 S_IRGRP = 0x0020; // group has read permission
|
||||
|
||||
private static UInt32 S_IWGRP = 0x0010; // group has write permission
|
||||
|
||||
private static UInt32 S_IXGRP = 0x0008; // group has execute permission
|
||||
|
||||
private static UInt32 S_IROTH = 0x0004; // others have read permission
|
||||
|
||||
private static UInt32 S_IWOTH = 0x0002; // others have write permission
|
||||
|
||||
private static UInt32 S_IXOTH = 0x0001; // others have execute permission
|
||||
|
||||
#endregion
|
||||
|
||||
private bool _isBitFiledsBitSet;
|
||||
private bool _isUIDBitSet;
|
||||
private bool _isGroupIDBitSet;
|
||||
private bool _isStickyBitSet;
|
||||
|
||||
private SftpSession _sftpSession;
|
||||
|
||||
public SftpFileAttributes Attributes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SftpFile"/> class.
|
||||
/// </summary>
|
||||
@@ -75,77 +28,11 @@ namespace Renci.SshNet.Sftp
|
||||
throw new ArgumentNullException("attributes");
|
||||
|
||||
this._sftpSession = sftpSession;
|
||||
this.Attributes = attributes;
|
||||
|
||||
this.Name = fullName.Substring(fullName.LastIndexOf('/') + 1);
|
||||
|
||||
this.FullName = fullName;
|
||||
|
||||
if (attributes.AccessTime.HasValue)
|
||||
this.LastAccessTime = attributes.AccessTime.Value;
|
||||
else
|
||||
this.LastAccessTime = DateTime.MinValue;
|
||||
|
||||
if (attributes.ModifyTime.HasValue)
|
||||
this.LastWriteTime = attributes.ModifyTime.Value;
|
||||
else
|
||||
this.LastWriteTime = DateTime.MinValue;
|
||||
|
||||
if (attributes.Size.HasValue)
|
||||
this.Size = (long)attributes.Size.Value;
|
||||
else
|
||||
this.Size = -1;
|
||||
|
||||
if (attributes.UserId.HasValue)
|
||||
this.UserId = (int)attributes.UserId.Value;
|
||||
else
|
||||
this.UserId = -1;
|
||||
|
||||
if (attributes.GroupId.HasValue)
|
||||
this.GroupId = (int)attributes.GroupId.Value;
|
||||
else
|
||||
this.GroupId = -1;
|
||||
|
||||
this._isBitFiledsBitSet = ((attributes.Permissions & S_IFMT) == S_IFMT);
|
||||
|
||||
this.IsSocket = ((attributes.Permissions & S_IFSOCK) == S_IFSOCK);
|
||||
|
||||
this.IsSymbolicLink = ((attributes.Permissions & S_IFLNK) == S_IFLNK);
|
||||
|
||||
this.IsRegularFile = ((attributes.Permissions & S_IFREG) == S_IFREG);
|
||||
|
||||
this.IsBlockDevice = ((attributes.Permissions & S_IFBLK) == S_IFBLK);
|
||||
|
||||
this.IsDirectory = ((attributes.Permissions & S_IFDIR) == S_IFDIR);
|
||||
|
||||
this.IsCharacterDevice = ((attributes.Permissions & S_IFCHR) == S_IFCHR);
|
||||
|
||||
this.IsNamedPipe = ((attributes.Permissions & S_IFIFO) == S_IFIFO);
|
||||
|
||||
this._isUIDBitSet = ((attributes.Permissions & S_ISUID) == S_ISUID);
|
||||
|
||||
this._isGroupIDBitSet = ((attributes.Permissions & S_ISGID) == S_ISGID);
|
||||
|
||||
this._isStickyBitSet = ((attributes.Permissions & S_ISVTX) == S_ISVTX);
|
||||
|
||||
this.OwnerCanRead = ((attributes.Permissions & S_IRUSR) == S_IRUSR);
|
||||
|
||||
this.OwnerCanWrite = ((attributes.Permissions & S_IWUSR) == S_IWUSR);
|
||||
|
||||
this.OwnerCanExecute = ((attributes.Permissions & S_IXUSR) == S_IXUSR);
|
||||
|
||||
this.GroupCanRead = ((attributes.Permissions & S_IRGRP) == S_IRGRP);
|
||||
|
||||
this.GroupCanWrite = ((attributes.Permissions & S_IWGRP) == S_IWGRP);
|
||||
|
||||
this.GroupCanExecute = ((attributes.Permissions & S_IXGRP) == S_IXGRP);
|
||||
|
||||
this.OthersCanRead = ((attributes.Permissions & S_IROTH) == S_IROTH);
|
||||
|
||||
this.OthersCanWrite = ((attributes.Permissions & S_IWOTH) == S_IWOTH);
|
||||
|
||||
this.OthersCanExecute = ((attributes.Permissions & S_IXOTH) == S_IXOTH);
|
||||
|
||||
this.Extensions = attributes.Extensions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -165,7 +52,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// The time that the current file or directory was last accessed.
|
||||
/// </value>
|
||||
public DateTime LastAccessTime { get; private set; }
|
||||
public DateTime LastAccessTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.LastAccessTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the time when the current file or directory was last written to.
|
||||
@@ -173,7 +66,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// The time the current file was last written.
|
||||
/// </value>
|
||||
public DateTime LastWriteTime { get; private set; }
|
||||
public DateTime LastWriteTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.LastWriteTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size, in bytes, of the current file.
|
||||
@@ -181,7 +80,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// The size of the current file in bytes.
|
||||
/// </value>
|
||||
public long Size { get; private set; }
|
||||
public long Size
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.Size;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets file user id.
|
||||
@@ -189,7 +94,17 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// File user id.
|
||||
/// </value>
|
||||
public int UserId { get; set; }
|
||||
public int UserId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.UserId;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.UserId = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets file group id.
|
||||
@@ -197,7 +112,17 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// File group id.
|
||||
/// </value>
|
||||
public int GroupId { get; set; }
|
||||
public int GroupId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.GroupId;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.GroupId = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether file represents a socket.
|
||||
@@ -205,7 +130,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// <c>true</c> if file represents a socket; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsSocket { get; private set; }
|
||||
public bool IsSocket
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.IsSocket;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether file represents a symbolic link.
|
||||
@@ -213,7 +144,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// <c>true</c> if file represents a symbolic link; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsSymbolicLink { get; private set; }
|
||||
public bool IsSymbolicLink
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.IsSymbolicLink;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether file represents a regular file.
|
||||
@@ -221,7 +158,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// <c>true</c> if file represents a regular file; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsRegularFile { get; private set; }
|
||||
public bool IsRegularFile
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.IsRegularFile;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether file represents a block device.
|
||||
@@ -229,7 +172,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// <c>true</c> if file represents a block device; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsBlockDevice { get; private set; }
|
||||
public bool IsBlockDevice
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.IsBlockDevice;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether file represents a directory.
|
||||
@@ -237,7 +186,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// <c>true</c> if file represents a directory; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsDirectory { get; private set; }
|
||||
public bool IsDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.IsDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether file represents a character device.
|
||||
@@ -245,7 +200,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// <c>true</c> if file represents a character device; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsCharacterDevice { get; private set; }
|
||||
public bool IsCharacterDevice
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.IsCharacterDevice;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether file represents a named pipe.
|
||||
@@ -253,79 +214,175 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// <c>true</c> if file represents a named pipe; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsNamedPipe { get; private set; }
|
||||
public bool IsNamedPipe
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.IsNamedPipe;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the owner can read from this file.
|
||||
/// Gets or sets a value indicating whether the owner can read from this file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if owner can read from this file; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool OwnerCanRead { get; set; }
|
||||
public bool OwnerCanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.OwnerCanRead;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.OwnerCanRead = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the owner can write into this file.
|
||||
/// Gets or sets a value indicating whether the owner can write into this file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if owner can write into this file; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool OwnerCanWrite { get; set; }
|
||||
public bool OwnerCanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.OwnerCanWrite;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.OwnerCanWrite = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the owner can execute this file.
|
||||
/// Gets or sets a value indicating whether the owner can execute this file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if owner can execute this file; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool OwnerCanExecute { get; set; }
|
||||
public bool OwnerCanExecute
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.OwnerCanExecute;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.OwnerCanExecute = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the group members can read from this file.
|
||||
/// Gets or sets a value indicating whether the group members can read from this file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if group members can read from this file; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool GroupCanRead { get; set; }
|
||||
public bool GroupCanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.GroupCanRead;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.GroupCanRead = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the group members can write into this file.
|
||||
/// Gets or sets a value indicating whether the group members can write into this file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if group members can write into this file; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool GroupCanWrite { get; set; }
|
||||
public bool GroupCanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.GroupCanWrite;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.GroupCanWrite = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the group members can execute this file.
|
||||
/// Gets or sets a value indicating whether the group members can execute this file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if group members can execute this file; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool GroupCanExecute { get; set; }
|
||||
public bool GroupCanExecute
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.GroupCanExecute;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.GroupCanExecute = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the others can read from this file.
|
||||
/// Gets or sets a value indicating whether the others can read from this file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if others can read from this file; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool OthersCanRead { get; set; }
|
||||
public bool OthersCanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.OthersCanRead;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.OthersCanRead = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the others can write into this file.
|
||||
/// Gets or sets a value indicating whether the others can write into this file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if others can write into this file; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool OthersCanWrite { get; set; }
|
||||
public bool OthersCanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.OthersCanWrite;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.OthersCanWrite = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the others can execute this file.
|
||||
/// Gets or sets a value indicating whether the others can execute this file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if others can execute this file; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool OthersCanExecute { get; set; }
|
||||
public bool OthersCanExecute
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.OthersCanExecute;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Attributes.OthersCanExecute = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the extension part of the file.
|
||||
@@ -335,41 +392,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// </value>
|
||||
public IDictionary<string, string> Extensions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Updates file status on the server.
|
||||
/// </summary>
|
||||
public void UpdateStatus()
|
||||
{
|
||||
using (var setCmd = new SetFileStatusCommand(this._sftpSession, this.FullName, this.GetAttributes()))
|
||||
{
|
||||
setCmd.CommandTimeout = TimeSpan.FromSeconds(30);
|
||||
|
||||
setCmd.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets file permissions.
|
||||
/// </summary>
|
||||
/// <param name="mode">The mode.</param>
|
||||
public void SetPermissions(ushort mode)
|
||||
public void SetPermissions(short mode)
|
||||
{
|
||||
var modeBytes = mode.ToString(CultureInfo.InvariantCulture).ToArray();
|
||||
|
||||
var permission = (modeBytes[0] & 0x0F) * 8 * 8 + (modeBytes[1] & 0x0F) * 8 + (modeBytes[2] & 0x0F);
|
||||
|
||||
|
||||
this.OwnerCanRead = (permission & S_IRUSR) == S_IRUSR;
|
||||
this.OwnerCanWrite = (permission & S_IWUSR) == S_IWUSR;
|
||||
this.OwnerCanExecute = (permission & S_IXUSR) == S_IXUSR;
|
||||
|
||||
this.GroupCanRead = (permission & S_IRGRP) == S_IRGRP;
|
||||
this.GroupCanWrite = (permission & S_IWGRP) == S_IWGRP;
|
||||
this.GroupCanExecute = (permission & S_IXGRP) == S_IXGRP;
|
||||
|
||||
this.OthersCanRead = (permission & S_IROTH) == S_IROTH;
|
||||
this.OthersCanWrite = (permission & S_IWOTH) == S_IWOTH;
|
||||
this.OthersCanExecute = (permission & S_IXOTH) == S_IXOTH;
|
||||
this.Attributes.SetPermissions(mode);
|
||||
|
||||
this.UpdateStatus();
|
||||
}
|
||||
@@ -377,7 +406,6 @@ namespace Renci.SshNet.Sftp
|
||||
/// <summary>
|
||||
/// Permanently deletes a file on remote machine.
|
||||
/// </summary>
|
||||
[SecuritySafeCritical]
|
||||
public void Delete()
|
||||
{
|
||||
SftpCommand cmd = null;
|
||||
@@ -409,7 +437,6 @@ namespace Renci.SshNet.Sftp
|
||||
/// Moves a specified file to a new location on remote machine, providing the option to specify a new file name.
|
||||
/// </summary>
|
||||
/// <param name="destFileName">The path to move the file to, which can specify a different file name.</param>
|
||||
[SecuritySafeCritical]
|
||||
public void MoveTo(string destFileName)
|
||||
{
|
||||
using (var setCmd = new RenameFileCommand(this._sftpSession, this.FullName, destFileName))
|
||||
@@ -421,99 +448,19 @@ namespace Renci.SshNet.Sftp
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file attributes.
|
||||
/// Updates file status on the server.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private SftpFileAttributes GetAttributes()
|
||||
public void UpdateStatus()
|
||||
{
|
||||
var attributes = new SftpFileAttributes();
|
||||
|
||||
// Populate only updateable attributes
|
||||
if (this.UserId > -1)
|
||||
using (var setCmd = new SetStatusCommand(this._sftpSession, this.FullName, this.Attributes))
|
||||
{
|
||||
attributes.UserId = new Nullable<uint>((uint)this.UserId);
|
||||
setCmd.CommandTimeout = TimeSpan.FromSeconds(30);
|
||||
|
||||
setCmd.Execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
attributes.UserId = null;
|
||||
}
|
||||
|
||||
if (this.GroupId > -1)
|
||||
{
|
||||
attributes.GroupId = new Nullable<uint>((uint)this.GroupId);
|
||||
}
|
||||
else
|
||||
{
|
||||
attributes.GroupId = null;
|
||||
}
|
||||
|
||||
UInt32 permission = 0;
|
||||
|
||||
if (this._isBitFiledsBitSet)
|
||||
permission = permission | S_IFMT;
|
||||
|
||||
if (this.IsSocket)
|
||||
permission = permission | S_IFSOCK;
|
||||
|
||||
if (this.IsSymbolicLink)
|
||||
permission = permission | S_IFLNK;
|
||||
|
||||
if (this.IsRegularFile)
|
||||
permission = permission | S_IFREG;
|
||||
|
||||
if (this.IsBlockDevice)
|
||||
permission = permission | S_IFBLK;
|
||||
|
||||
if (this.IsDirectory)
|
||||
permission = permission | S_IFDIR;
|
||||
|
||||
if (this.IsCharacterDevice)
|
||||
permission = permission | S_IFCHR;
|
||||
|
||||
if (this.IsNamedPipe)
|
||||
permission = permission | S_IFIFO;
|
||||
|
||||
if (this._isUIDBitSet)
|
||||
permission = permission | S_ISUID;
|
||||
|
||||
if (this._isGroupIDBitSet)
|
||||
permission = permission | S_ISGID;
|
||||
|
||||
if (this._isStickyBitSet)
|
||||
permission = permission | S_ISVTX;
|
||||
|
||||
if (this.OwnerCanRead)
|
||||
permission = permission | S_IRUSR;
|
||||
|
||||
if (this.OwnerCanWrite)
|
||||
permission = permission | S_IWUSR;
|
||||
|
||||
if (this.OwnerCanExecute)
|
||||
permission = permission | S_IXUSR;
|
||||
|
||||
if (this.GroupCanRead)
|
||||
permission = permission | S_IRGRP;
|
||||
|
||||
if (this.GroupCanWrite)
|
||||
permission = permission | S_IWGRP;
|
||||
|
||||
if (this.GroupCanExecute)
|
||||
permission = permission | S_IXGRP;
|
||||
|
||||
if (this.OthersCanRead)
|
||||
permission = permission | S_IROTH;
|
||||
|
||||
if (this.OthersCanWrite)
|
||||
permission = permission | S_IWOTH;
|
||||
|
||||
if (this.OthersCanExecute)
|
||||
permission = permission | S_IXOTH;
|
||||
|
||||
attributes.Permissions = permission;
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents this instance.
|
||||
/// </summary>
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Renci.SshNet.Sftp
|
||||
{
|
||||
public class SftpFileAttributes1
|
||||
public class SftpFileAttributes
|
||||
{
|
||||
#region Bitmask constats
|
||||
|
||||
@@ -50,7 +51,7 @@ namespace Renci.SshNet.Sftp
|
||||
private static UInt32 S_IXOTH = 0x0001; // others have execute permission
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private bool _isBitFiledsBitSet;
|
||||
private bool _isUIDBitSet;
|
||||
private bool _isGroupIDBitSet;
|
||||
@@ -78,7 +79,7 @@ namespace Renci.SshNet.Sftp
|
||||
/// <value>
|
||||
/// The size of the current file in bytes.
|
||||
/// </value>
|
||||
public long Size { get; private set; }
|
||||
public long Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets file user id.
|
||||
@@ -345,7 +346,19 @@ namespace Renci.SshNet.Sftp
|
||||
}
|
||||
}
|
||||
|
||||
internal SftpFileAttributes1(DateTime lastAccessTime, DateTime lastWriteTime, long size, int userId, int groupId, uint permissions)
|
||||
private static SftpFileAttributes _empty = new SftpFileAttributes(DateTime.MinValue, DateTime.MinValue, -1, -1, -1, 0, null);
|
||||
/// <summary>
|
||||
/// Gets the empty SftpFileAttributes instance.
|
||||
/// </summary>
|
||||
public static SftpFileAttributes Empty
|
||||
{
|
||||
get
|
||||
{
|
||||
return SftpFileAttributes._empty;
|
||||
}
|
||||
}
|
||||
|
||||
internal SftpFileAttributes(DateTime lastAccessTime, DateTime lastWriteTime, long size, int userId, int groupId, uint permissions, IDictionary<string, string> extensions)
|
||||
{
|
||||
this.LastAccessTime = lastAccessTime;
|
||||
this.LastWriteTime = lastWriteTime;
|
||||
@@ -353,6 +366,31 @@ namespace Renci.SshNet.Sftp
|
||||
this.UserId = userId;
|
||||
this.GroupId = groupId;
|
||||
this.Permissions = permissions;
|
||||
this.Extensions = extensions;
|
||||
}
|
||||
|
||||
public void SetPermissions(short mode)
|
||||
{
|
||||
if (mode < 0 || mode > 999)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("mode");
|
||||
}
|
||||
|
||||
var modeBytes = mode.ToString(CultureInfo.InvariantCulture).PadLeft(3,'0').ToArray();
|
||||
|
||||
var permission = (modeBytes[0] & 0x0F) * 8 * 8 + (modeBytes[1] & 0x0F) * 8 + (modeBytes[2] & 0x0F);
|
||||
|
||||
this.OwnerCanRead = (permission & S_IRUSR) == S_IRUSR;
|
||||
this.OwnerCanWrite = (permission & S_IWUSR) == S_IWUSR;
|
||||
this.OwnerCanExecute = (permission & S_IXUSR) == S_IXUSR;
|
||||
|
||||
this.GroupCanRead = (permission & S_IRGRP) == S_IRGRP;
|
||||
this.GroupCanWrite = (permission & S_IWGRP) == S_IWGRP;
|
||||
this.GroupCanExecute = (permission & S_IXGRP) == S_IXGRP;
|
||||
|
||||
this.OthersCanRead = (permission & S_IROTH) == S_IROTH;
|
||||
this.OthersCanWrite = (permission & S_IWOTH) == S_IWOTH;
|
||||
this.OthersCanExecute = (permission & S_IXOTH) == S_IXOTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,10 +109,9 @@ namespace Renci.SshNet.Sftp
|
||||
// Update file attributes
|
||||
this._attributes = this._session.GetFileAttributes(this._handle);
|
||||
|
||||
if (this._attributes != null && this._attributes.Size.HasValue)
|
||||
if (this._attributes != null && this._attributes.Size > -1)
|
||||
{
|
||||
// TODO: Test file size that greater then long.Max
|
||||
return (long)this._attributes.Size.Value;
|
||||
return this._attributes.Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -291,7 +290,7 @@ namespace Renci.SshNet.Sftp
|
||||
if (mode == FileMode.Append)
|
||||
{
|
||||
// TODO: Validate Size property value exists
|
||||
this._position = (long)this._attributes.Size.Value;
|
||||
this._position = this._attributes.Size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -681,7 +680,7 @@ namespace Renci.SshNet.Sftp
|
||||
newPosn = this._position + offset;
|
||||
break;
|
||||
case SeekOrigin.End:
|
||||
newPosn = ((long)this._attributes.Size.Value) - offset;
|
||||
newPosn = this._attributes.Size - offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -726,7 +725,6 @@ namespace Renci.SshNet.Sftp
|
||||
this._bufferLen = 0;
|
||||
|
||||
// Seek to the new position.
|
||||
//newPosn = FileMethods.Seek(this._handle, offset, origin);
|
||||
switch (origin)
|
||||
{
|
||||
case SeekOrigin.Begin:
|
||||
@@ -736,16 +734,17 @@ namespace Renci.SshNet.Sftp
|
||||
newPosn = this._position + offset;
|
||||
break;
|
||||
case SeekOrigin.End:
|
||||
newPosn = ((long)this._attributes.Size.Value) - offset;
|
||||
newPosn = this._attributes.Size - offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (newPosn == -1)
|
||||
if (newPosn < 0)
|
||||
{
|
||||
throw new EndOfStreamException();
|
||||
}
|
||||
|
||||
this._position = newPosn;
|
||||
}
|
||||
return this._position;
|
||||
@@ -779,7 +778,7 @@ namespace Renci.SshNet.Sftp
|
||||
// Setup this object for writing.
|
||||
this.SetupWrite();
|
||||
|
||||
this._attributes.Size = (ulong)value;
|
||||
this._attributes.Size = value;
|
||||
|
||||
this._session.SetFileAttributes(this._handle, this._attributes);
|
||||
}
|
||||
|
||||
@@ -212,6 +212,18 @@ namespace Renci.SshNet.Sftp
|
||||
}
|
||||
}
|
||||
|
||||
public SftpFileAttributes GetFileAttributes(string path)
|
||||
{
|
||||
using (var cmd = new StatusCommand(this, path))
|
||||
{
|
||||
cmd.CommandTimeout = this._operationTimeout;
|
||||
|
||||
cmd.Execute();
|
||||
|
||||
return cmd.Attributes;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFileAttributes(byte[] handle, SftpFileAttributes attributes)
|
||||
{
|
||||
using (var cmd = new SetStatusCommand(this, handle, attributes))
|
||||
@@ -222,6 +234,17 @@ namespace Renci.SshNet.Sftp
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFileAttributes(string path, SftpFileAttributes attributes)
|
||||
{
|
||||
using (var cmd = new SetStatusCommand(this, path, attributes))
|
||||
{
|
||||
cmd.CommandTimeout = this._operationTimeout;
|
||||
|
||||
cmd.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal void SendMessage(SftpMessage sftpMessage)
|
||||
{
|
||||
this._session.SendMessage(new SftpDataMessage(this._channel.RemoteChannelNumber, sftpMessage));
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace Renci.SshNet
|
||||
/// </summary>
|
||||
/// <param name="path">File(s) path, may match multiple files.</param>
|
||||
/// <param name="mode">The mode.</param>
|
||||
public void ChangePermissions(string path, ushort mode)
|
||||
public void ChangePermissions(string path, short mode)
|
||||
{
|
||||
if (path == null)
|
||||
throw new ArgumentNullException("path");
|
||||
@@ -705,16 +705,6 @@ namespace Renci.SshNet
|
||||
return file != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the System.IO.FileAttributes of the file on the path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the file.</param>
|
||||
/// <returns>The System.IO.FileAttributes of the file on the path.</returns>
|
||||
public FileAttributes GetAttributes(string path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the date and time the specified file or directory was last accessed.
|
||||
/// </summary>
|
||||
@@ -1036,12 +1026,35 @@ namespace Renci.SshNet
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="SftpFileAttributes"/> of the file on the path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the file.</param>
|
||||
/// <returns>The <see cref="SftpFileAttributes"/> of the file on the path.</returns>
|
||||
public SftpFileAttributes GetAttributes(string path)
|
||||
{
|
||||
var fullPath = this._sftpSession.GetCanonicalPath(path);
|
||||
|
||||
return this._sftpSession.GetFileAttributes(fullPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the specified <see cref="SftpFileAttributes"/> of the file on the specified path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the file.</param>
|
||||
/// <param name="fileAttributes">The desired <see cref="SftpFileAttributes"/>.</param>
|
||||
public void SetAttributes(string path, SftpFileAttributes fileAttributes)
|
||||
{
|
||||
var fullPath = this._sftpSession.GetCanonicalPath(path);
|
||||
|
||||
this._sftpSession.SetFileAttributes(fullPath, fileAttributes);
|
||||
}
|
||||
|
||||
//public FileSecurity GetAccessControl(string path);
|
||||
//public FileSecurity GetAccessControl(string path, AccessControlSections includeSections);
|
||||
//public DateTime GetCreationTime(string path);
|
||||
//public DateTime GetCreationTimeUtc(string path);
|
||||
//public void SetAccessControl(string path, FileSecurity fileSecurity);
|
||||
//public void SetAttributes(string path, FileAttributes fileAttributes);
|
||||
//public void SetCreationTime(string path, DateTime creationTime);
|
||||
//public void SetCreationTimeUtc(string path, DateTime creationTimeUtc);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user