You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Lidarr/src/NzbDrone.Mono/DiskProvider.cs

171 lines
5.0 KiB

using System;
using System.IO;
using System.Linq;
using Mono.Unix.Native;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnsureThat;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation;
using Mono.Unix;
namespace NzbDrone.Mono
{
public class DiskProvider : DiskProviderBase
{
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(DiskProvider));
public override long? GetAvailableSpace(string path)
{
Ensure.That(path, () => path).IsValidPath();
var root = GetPathRoot(path);
if (!FolderExists(root))
throw new DirectoryNotFoundException(root);
try
{
var driveInfo = GetDriveInfo(path);
if (driveInfo == null)
{
Logger.Debug("Unable to get free space for '{0}', unable to find suitable drive", path);
return null;
}
return driveInfo.AvailableFreeSpace;
}
catch (InvalidOperationException ex)
{
Logger.ErrorException("Couldn't get free space for " + path, ex);
}
return null;
}
public override void InheritFolderPermissions(string filename)
{
Ensure.That(filename, () => filename).IsValidPath();
try
{
var fs = File.GetAccessControl(filename);
fs.SetAccessRuleProtection(false, false);
File.SetAccessControl(filename, fs);
}
catch (NotImplementedException)
{
}
catch (PlatformNotSupportedException)
{
}
}
public override void SetPermissions(string path, string mask, string user, string group)
{
Logger.Debug("Setting permissions: {0} on {1}", mask, path);
var filePermissions = NativeConvert.FromOctalPermissionString(mask);
if (Syscall.chmod(path, filePermissions) < 0)
{
var error = Stdlib.GetLastError();
throw new LinuxPermissionsException("Error setting file permissions: " + error);
}
if (String.IsNullOrWhiteSpace(user) || String.IsNullOrWhiteSpace(group))
{
Logger.Debug("User or Group for chown not configured, skipping chown.");
return;
}
uint userId;
uint groupId;
if (!uint.TryParse(user, out userId))
{
var u = Syscall.getpwnam(user);
if (u == null)
{
throw new LinuxPermissionsException("Unknown user: {0}", user);
}
userId = u.pw_uid;
}
if (!uint.TryParse(group, out groupId))
{
var g = Syscall.getgrnam(group);
if (g == null)
{
throw new LinuxPermissionsException("Unknown group: {0}", group);
}
groupId = g.gr_gid;
}
if (Syscall.chown(path, userId, groupId) < 0)
{
var error = Stdlib.GetLastError();
throw new LinuxPermissionsException("Error setting file owner and/or group: " + error);
}
}
public override long? GetTotalSize(string path)
{
Ensure.That(path, () => path).IsValidPath();
var root = GetPathRoot(path);
if (!FolderExists(root))
throw new DirectoryNotFoundException(root);
try
{
var driveInfo = GetDriveInfo(path);
if (driveInfo == null) return null;
return driveInfo.TotalSize;
}
catch (InvalidOperationException e)
{
Logger.ErrorException("Couldn't get total space for " + path, e);
}
return null;
}
private DriveInfo GetDriveInfo(string path)
{
var drives = DriveInfo.GetDrives();
return
drives.Where(drive => drive.IsReady &&
drive.Name.IsNotNullOrWhiteSpace() &&
path.StartsWith(drive.Name, StringComparison.CurrentCultureIgnoreCase))
.OrderByDescending(drive => drive.Name.Length)
.FirstOrDefault();
}
public override bool TryCreateHardLink(string source, string destination)
{
try
{
UnixFileSystemInfo.GetFileSystemEntry(source).CreateLink(destination);
return true;
}
catch (Exception ex)
{
Logger.DebugException(String.Format("Hardlink '{0}' to '{1}' failed.", source, destination), ex);
return false;
}
}
}
}