SftpFileAttributes
Contains SFTP file attributes.
using Renci.SshNet.Common;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Renci.SshNet.Sftp
{
public class SftpFileAttributes
{
private const uint S_IFMT = 61440;
private const uint S_IFSOCK = 49152;
private const uint S_IFLNK = 40960;
private const uint S_IFREG = 32768;
private const uint S_IFBLK = 24576;
private const uint S_IFDIR = 16384;
private const uint S_IFCHR = 8192;
private const uint S_IFIFO = 4096;
private const uint S_ISUID = 2048;
private const uint S_ISGID = 1024;
private const uint S_ISVTX = 512;
private const uint S_IRUSR = 256;
private const uint S_IWUSR = 128;
private const uint S_IXUSR = 64;
private const uint S_IRGRP = 32;
private const uint S_IWGRP = 16;
private const uint S_IXGRP = 8;
private const uint S_IROTH = 4;
private const uint S_IWOTH = 2;
private const uint S_IXOTH = 1;
private bool _isBitFiledsBitSet;
private bool _isUIDBitSet;
private bool _isGroupIDBitSet;
private bool _isStickyBitSet;
private readonly DateTime _originalLastAccessTime;
private readonly DateTime _originalLastWriteTime;
private readonly long _originalSize;
private readonly int _originalUserId;
private readonly int _originalGroupId;
private readonly uint _originalPermissions;
private readonly IDictionary<string, string> _originalExtensions;
internal static readonly SftpFileAttributes Empty = new SftpFileAttributes();
internal bool IsLastAccessTimeChanged => _originalLastAccessTime != LastAccessTime;
internal bool IsLastWriteTimeChanged => _originalLastWriteTime != LastWriteTime;
internal bool IsSizeChanged => _originalSize != Size;
internal bool IsUserIdChanged => _originalUserId != UserId;
internal bool IsGroupIdChanged => _originalGroupId != GroupId;
internal bool IsPermissionsChanged => _originalPermissions != Permissions;
internal bool IsExtensionsChanged {
get {
if (_originalExtensions != null && Extensions != null)
return !_originalExtensions.SequenceEqual(Extensions);
return false;
}
}
public DateTime LastAccessTime { get; set; }
public DateTime LastWriteTime { get; set; }
public long Size { get; set; }
public int UserId { get; set; }
public int GroupId { get; set; }
public bool IsSocket { get; set; }
public bool IsSymbolicLink { get; set; }
public bool IsRegularFile { get; set; }
public bool IsBlockDevice { get; set; }
public bool IsDirectory { get; set; }
public bool IsCharacterDevice { get; set; }
public bool IsNamedPipe { get; set; }
public bool OwnerCanRead { get; set; }
public bool OwnerCanWrite { get; set; }
public bool OwnerCanExecute { get; set; }
public bool GroupCanRead { get; set; }
public bool GroupCanWrite { get; set; }
public bool GroupCanExecute { get; set; }
public bool OthersCanRead { get; set; }
public bool OthersCanWrite { get; set; }
public bool OthersCanExecute { get; set; }
public IDictionary<string, string> Extensions { get; set; }
internal uint Permissions {
get {
uint num = 0;
if (_isBitFiledsBitSet)
num |= 61440;
if (IsSocket)
num |= 49152;
if (IsSymbolicLink)
num |= 40960;
if (IsRegularFile)
num |= 32768;
if (IsBlockDevice)
num |= 24576;
if (IsDirectory)
num |= 16384;
if (IsCharacterDevice)
num |= 8192;
if (IsNamedPipe)
num |= 4096;
if (_isUIDBitSet)
num |= 2048;
if (_isGroupIDBitSet)
num |= 1024;
if (_isStickyBitSet)
num |= 512;
if (OwnerCanRead)
num |= 256;
if (OwnerCanWrite)
num |= 128;
if (OwnerCanExecute)
num |= 64;
if (GroupCanRead)
num |= 32;
if (GroupCanWrite)
num |= 16;
if (GroupCanExecute)
num |= 8;
if (OthersCanRead)
num |= 4;
if (OthersCanWrite)
num |= 2;
if (OthersCanExecute)
num |= 1;
return num;
}
private set {
_isBitFiledsBitSet = ((value & 61440) == 61440);
IsSocket = ((value & 49152) == 49152);
IsSymbolicLink = ((value & 40960) == 40960);
IsRegularFile = ((value & 32768) == 32768);
IsBlockDevice = ((value & 24576) == 24576);
IsDirectory = ((value & 16384) == 16384);
IsCharacterDevice = ((value & 8192) == 8192);
IsNamedPipe = ((value & 4096) == 4096);
_isUIDBitSet = ((value & 2048) == 2048);
_isGroupIDBitSet = ((value & 1024) == 1024);
_isStickyBitSet = ((value & 512) == 512);
OwnerCanRead = ((value & 256) == 256);
OwnerCanWrite = ((value & 128) == 128);
OwnerCanExecute = ((value & 64) == 64);
GroupCanRead = ((value & 32) == 32);
GroupCanWrite = ((value & 16) == 16);
GroupCanExecute = ((value & 8) == 8);
OthersCanRead = ((value & 4) == 4);
OthersCanWrite = ((value & 2) == 2);
OthersCanExecute = ((value & 1) == 1);
}
}
private SftpFileAttributes()
{
}
internal SftpFileAttributes(DateTime lastAccessTime, DateTime lastWriteTime, long size, int userId, int groupId, uint permissions, IDictionary<string, string> extensions)
{
LastAccessTime = (_originalLastAccessTime = lastAccessTime);
LastWriteTime = (_originalLastWriteTime = lastWriteTime);
Size = (_originalSize = size);
UserId = (_originalUserId = userId);
GroupId = (_originalGroupId = groupId);
Permissions = (_originalPermissions = permissions);
Extensions = (_originalExtensions = extensions);
}
public void SetPermissions(short mode)
{
if (mode < 0 || mode > 999)
throw new ArgumentOutOfRangeException("mode");
char[] array = mode.ToString(CultureInfo.InvariantCulture).PadLeft(3, '0').ToCharArray();
int num = (array[0] & 15) * 8 * 8 + (array[1] & 15) * 8 + (array[2] & 15);
OwnerCanRead = (((long)num & 256) == 256);
OwnerCanWrite = (((long)num & 128) == 128);
OwnerCanExecute = (((long)num & 64) == 64);
GroupCanRead = (((long)num & 32) == 32);
GroupCanWrite = (((long)num & 16) == 16);
GroupCanExecute = (((long)num & 8) == 8);
OthersCanRead = (((long)num & 4) == 4);
OthersCanWrite = (((long)num & 2) == 2);
OthersCanExecute = (((long)num & 1) == 1);
}
public byte[] GetBytes()
{
SshDataStream sshDataStream = new SshDataStream(4);
uint num = 0;
if (IsSizeChanged && IsRegularFile)
num |= 1;
if (IsUserIdChanged || IsGroupIdChanged)
num |= 2;
if (IsPermissionsChanged)
num |= 4;
if (IsLastAccessTimeChanged || IsLastWriteTimeChanged)
num |= 8;
if (IsExtensionsChanged)
num = (uint)((int)num | -2147483648);
sshDataStream.Write(num);
if (IsSizeChanged && IsRegularFile)
sshDataStream.Write((ulong)Size);
if (IsUserIdChanged || IsGroupIdChanged) {
sshDataStream.Write((uint)UserId);
sshDataStream.Write((uint)GroupId);
}
if (IsPermissionsChanged)
sshDataStream.Write(Permissions);
if (IsLastAccessTimeChanged || IsLastWriteTimeChanged) {
DateTime dateTime = LastAccessTime;
uint value = (uint)(dateTime.ToFileTime() / 10000000 - 11644473600);
sshDataStream.Write(value);
dateTime = LastWriteTime;
value = (uint)(dateTime.ToFileTime() / 10000000 - 11644473600);
sshDataStream.Write(value);
}
if (IsExtensionsChanged) {
foreach (KeyValuePair<string, string> extension in Extensions) {
sshDataStream.Write(extension.Key, SshData.Ascii);
sshDataStream.Write(extension.Value, SshData.Ascii);
}
}
return sshDataStream.ToArray();
}
internal static SftpFileAttributes FromBytes(SshDataStream stream)
{
uint num = stream.ReadUInt32();
long size = -1;
int userId = -1;
int groupId = -1;
uint permissions = 0;
DateTime lastAccessTime = DateTime.MinValue;
DateTime lastWriteTime = DateTime.MinValue;
IDictionary<string, string> dictionary = null;
if ((num & 1) == 1)
size = (long)stream.ReadUInt64();
if ((num & 2) == 2) {
userId = (int)stream.ReadUInt32();
groupId = (int)stream.ReadUInt32();
}
if ((num & 4) == 4)
permissions = stream.ReadUInt32();
if ((num & 8) == 8) {
lastAccessTime = DateTime.FromFileTime((stream.ReadUInt32() + 11644473600) * 10000000);
lastWriteTime = DateTime.FromFileTime((stream.ReadUInt32() + 11644473600) * 10000000);
}
if (((int)num & -2147483648) == -2147483648) {
int num2 = (int)stream.ReadUInt32();
dictionary = new Dictionary<string, string>(num2);
for (int i = 0; i < num2; i++) {
string key = stream.ReadString(SshData.Utf8);
string value = stream.ReadString(SshData.Utf8);
dictionary.Add(key, value);
}
}
return new SftpFileAttributes(lastAccessTime, lastWriteTime, size, userId, groupId, permissions, dictionary);
}
internal static SftpFileAttributes FromBytes(byte[] buffer)
{
using (SshDataStream stream = new SshDataStream(buffer))
return FromBytes(stream);
}
}
}