Refactor SftpFileAttributes class to be public

Add SetAttributes and GetAttributes methods
This commit is contained in:
olegkap_cp
2011-06-07 20:25:12 +00:00
parent 4d79078a70
commit 2bea9352eb
11 changed files with 339 additions and 422 deletions
@@ -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();
}
}
}
}
+212 -265
View File
@@ -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));
+25 -12
View File
@@ -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);