From 917e2cd0c4627f3f51ea084034e77d3d470fb081 Mon Sep 17 00:00:00 2001 From: Jojo-1000 <33495614+Jojo-1000@users.noreply.github.com> Date: Thu, 30 May 2024 02:14:05 +0200 Subject: [PATCH] Remove obsolete custom platform detection. --- .../Database/ServerSettings.cs | 4 ++-- .../RESTMethods/Filesystem.cs | 4 ++-- .../RESTMethods/Licenses.cs | 2 +- .../RESTMethods/SystemInfo.cs | 2 +- Duplicati.Library.RestAPI/SpecialFolders.cs | 2 +- Duplicati/CommandLine/CLI/Help.cs | 6 +++--- .../Library/AutoUpdater/PackageHelper.cs | 20 +++++++++---------- .../Library/AutoUpdater/UpdaterManager.cs | 4 ++-- Duplicati/Library/Backend/File/FileBackend.cs | 11 ++++++---- Duplicati/Library/Common/Platform/Platform.cs | 7 +++++++ .../Main/Database/LocalBugReportDatabase.cs | 2 +- .../Main/Database/LocalRestoreDatabase.cs | 8 ++++---- Duplicati/Library/Main/DatabaseLocator.cs | 2 +- .../Library/Main/Operation/BackupHandler.cs | 1 + .../Modules/Builtin/ConsolePasswordInput.cs | 2 +- .../Library/Modules/Builtin/HyperVOptions.cs | 4 ++-- .../Library/Modules/Builtin/MSSQLOptions.cs | 4 ++-- Duplicati/Library/Snapshots/HyperVUtility.cs | 3 ++- Duplicati/Library/Snapshots/MSSQLUtility.cs | 2 +- Duplicati/Library/Snapshots/Program.cs | 2 +- Duplicati/Library/Snapshots/USNJournal.cs | 3 --- .../Library/UsageReporter/OSInfoHelper.cs | 4 ++-- Duplicati/Library/Utility/FilterGroups.cs | 8 ++++---- .../Utility/SslCertificateValidator.cs | 2 +- Duplicati/Library/Utility/UrlUtility.cs | 12 ++++++++--- Duplicati/Library/Utility/Utility.cs | 10 +++++----- Duplicati/Library/Utility/WinTools.cs | 3 ++- Duplicati/Server/Program.cs | 4 ++-- Duplicati/Server/SingleInstance.cs | 4 ++-- Duplicati/UnitTest/BasicSetupHelper.cs | 2 +- Duplicati/UnitTest/IOTests.cs | 13 ++++++------ Duplicati/UnitTest/ProblematicPathTests.cs | 7 ++++--- Duplicati/UnitTest/RestoreHandlerTests.cs | 5 +++-- Duplicati/UnitTest/RunScriptTests.cs | 4 ++-- Duplicati/UnitTest/TestUtils.cs | 2 +- 35 files changed, 97 insertions(+), 78 deletions(-) diff --git a/Duplicati.Library.RestAPI/Database/ServerSettings.cs b/Duplicati.Library.RestAPI/Database/ServerSettings.cs index 92b02bcfa..9e446b731 100644 --- a/Duplicati.Library.RestAPI/Database/ServerSettings.cs +++ b/Duplicati.Library.RestAPI/Database/ServerSettings.cs @@ -493,7 +493,7 @@ namespace Duplicati.Server.Database if (String.IsNullOrEmpty(settings[CONST.SERVER_SSL_CERTIFICATE])) return null; - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) return new X509Certificate2(Convert.FromBase64String(settings[CONST.SERVER_SSL_CERTIFICATE])); else return new X509Certificate2(Convert.FromBase64String(settings[CONST.SERVER_SSL_CERTIFICATE]), ""); @@ -507,7 +507,7 @@ namespace Duplicati.Server.Database } else { - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) lock (databaseConnection.m_lock) settings[CONST.SERVER_SSL_CERTIFICATE] = Convert.ToBase64String(value.Export(X509ContentType.Pkcs12)); else diff --git a/Duplicati.Library.RestAPI/RESTMethods/Filesystem.cs b/Duplicati.Library.RestAPI/RESTMethods/Filesystem.cs index 1b8c24490..d20f55382 100644 --- a/Duplicati.Library.RestAPI/RESTMethods/Filesystem.cs +++ b/Duplicati.Library.RestAPI/RESTMethods/Filesystem.cs @@ -72,7 +72,7 @@ namespace Duplicati.Server.WebServer.RESTMethods path = SpecialFolders.ExpandEnvironmentVariables(path); - if (Platform.IsClientPosix && !path.StartsWith("/", StringComparison.Ordinal)) + if ((OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) && !path.StartsWith("/", StringComparison.Ordinal)) { info.ReportClientError("The path parameter must start with a forward-slash", System.Net.HttpStatusCode.BadRequest); return; @@ -111,7 +111,7 @@ namespace Duplicati.Server.WebServer.RESTMethods IEnumerable res; - if (!Platform.IsClientPosix && (path.Equals("/") || path.Equals(""))) + if (!(OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) && (path.Equals("/") || path.Equals(""))) { res = DriveInfo.GetDrives() .Where(di => diff --git a/Duplicati.Library.RestAPI/RESTMethods/Licenses.cs b/Duplicati.Library.RestAPI/RESTMethods/Licenses.cs index 39bd5d754..b0987c0b9 100644 --- a/Duplicati.Library.RestAPI/RESTMethods/Licenses.cs +++ b/Duplicati.Library.RestAPI/RESTMethods/Licenses.cs @@ -29,7 +29,7 @@ namespace Duplicati.Server.WebServer.RESTMethods { var exefolder = System.IO.Path.GetDirectoryName(Duplicati.Library.Utility.Utility.getEntryAssembly().Location); var path = System.IO.Path.Combine(exefolder, "licenses"); - if (Duplicati.Library.Common.Platform.IsClientOSX && !Directory.Exists(path)) + if (OperatingSystem.IsMacOS() && !Directory.Exists(path)) { // Go up one, as the licenses cannot be in the binary folder in MacOS Packages exefolder = Path.GetDirectoryName(exefolder); diff --git a/Duplicati.Library.RestAPI/RESTMethods/SystemInfo.cs b/Duplicati.Library.RestAPI/RESTMethods/SystemInfo.cs index 93d5f780c..c65d63cfb 100644 --- a/Duplicati.Library.RestAPI/RESTMethods/SystemInfo.cs +++ b/Duplicati.Library.RestAPI/RESTMethods/SystemInfo.cs @@ -71,7 +71,7 @@ namespace Duplicati.Server.WebServer.RESTMethods DefaultUpdateChannel = Duplicati.Library.AutoUpdater.AutoUpdateSettings.DefaultUpdateChannel, DefaultUsageReportLevel = Duplicati.Library.UsageReporter.Reporter.DefaultReportLevel, ServerTime = DateTime.Now, - OSType = Platform.IsClientPosix ? (Platform.IsClientOSX ? "OSX" : "Linux") : "Windows", + OSType = OperatingSystem.IsWindows() ? "Windows" : (OperatingSystem.IsMacOS() ? "OSX" : "Linux"), DirectorySeparator = System.IO.Path.DirectorySeparatorChar, PathSeparator = System.IO.Path.PathSeparator, CaseSensitiveFilesystem = Duplicati.Library.Utility.Utility.IsFSCaseSensitive, diff --git a/Duplicati.Library.RestAPI/SpecialFolders.cs b/Duplicati.Library.RestAPI/SpecialFolders.cs index 5bcbd239f..6a83004f1 100644 --- a/Duplicati.Library.RestAPI/SpecialFolders.cs +++ b/Duplicati.Library.RestAPI/SpecialFolders.cs @@ -114,7 +114,7 @@ namespace Duplicati.Server { var lst = new List(); - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) { TryAdd(lst, Environment.SpecialFolder.MyDocuments, "%MY_DOCUMENTS%", "My Documents"); TryAdd(lst, Environment.SpecialFolder.MyMusic, "%MY_MUSIC%", "My Music"); diff --git a/Duplicati/CommandLine/CLI/Help.cs b/Duplicati/CommandLine/CLI/Help.cs index 9702d85f4..e5a3e51ae 100644 --- a/Duplicati/CommandLine/CLI/Help.cs +++ b/Duplicati/CommandLine/CLI/Help.cs @@ -120,9 +120,9 @@ namespace Duplicati.CommandLine tp = tp.Replace("%BACKENDS%", string.Join(", ", Library.DynamicLoader.BackendLoader.Keys)); tp = tp.Replace("%APP_PATH%", Path.Combine(UpdaterManager.INSTALLATIONDIR, PackageHelper.GetExecutableName(PackageHelper.NamedExecutable.CommandLine))); tp = tp.Replace("%PATH_SEPARATOR%", System.IO.Path.PathSeparator.ToString()); - tp = tp.Replace("%EXAMPLE_SOURCE_PATH%", Platform.IsClientPosix ? "/source" : @"D:\source"); - tp = tp.Replace("%EXAMPLE_SOURCE_FILE%", Platform.IsClientPosix ? "/source/myfile.txt" : @"D:\source\file.txt"); - tp = tp.Replace("%EXAMPLE_RESTORE_PATH%", Platform.IsClientPosix ? "/restore" : @"D:\restore"); + tp = tp.Replace("%EXAMPLE_SOURCE_PATH%", !OperatingSystem.IsWindows() ? "/source" : @"D:\source"); + tp = tp.Replace("%EXAMPLE_SOURCE_FILE%", !OperatingSystem.IsWindows() ? "/source/myfile.txt" : @"D:\source\file.txt"); + tp = tp.Replace("%EXAMPLE_RESTORE_PATH%", !OperatingSystem.IsWindows() ? "/restore" : @"D:\restore"); tp = tp.Replace("%ENCRYPTIONMODULES%", string.Join(", ", Library.DynamicLoader.EncryptionLoader.Keys)); tp = tp.Replace("%COMPRESSIONMODULES%", string.Join(", ", Library.DynamicLoader.CompressionLoader.Keys)); tp = tp.Replace("%DEFAULTENCRYPTIONMODULE%", opts.EncryptionModule); diff --git a/Duplicati/Library/AutoUpdater/PackageHelper.cs b/Duplicati/Library/AutoUpdater/PackageHelper.cs index 524506ba0..190a7ac8a 100644 --- a/Duplicati/Library/AutoUpdater/PackageHelper.cs +++ b/Duplicati/Library/AutoUpdater/PackageHelper.cs @@ -73,17 +73,17 @@ namespace Duplicati.Library.AutoUpdater public static string GetExecutableName(NamedExecutable exe) => exe switch { - NamedExecutable.TrayIcon => Platform.IsClientWindows ? "Duplicati.GUI.TrayIcon.exe" : "duplicati", - NamedExecutable.CommandLine => Platform.IsClientWindows ? "Duplicati.CommandLine.exe" : "duplicati-cli", - NamedExecutable.AutoUpdater => Platform.IsClientWindows ? "Duplicati.CommandLine.AutoUpdater.exe" : "duplicati-autoupdater", - NamedExecutable.Server => Platform.IsClientWindows ? "Duplicati.Server.exe" : "duplicati-server", + NamedExecutable.TrayIcon => OperatingSystem.IsWindows() ? "Duplicati.GUI.TrayIcon.exe" : "duplicati", + NamedExecutable.CommandLine => OperatingSystem.IsWindows() ? "Duplicati.CommandLine.exe" : "duplicati-cli", + NamedExecutable.AutoUpdater => OperatingSystem.IsWindows() ? "Duplicati.CommandLine.AutoUpdater.exe" : "duplicati-autoupdater", + NamedExecutable.Server => OperatingSystem.IsWindows() ? "Duplicati.Server.exe" : "duplicati-server", NamedExecutable.WindowsService => "Duplicati.WindowsServer.exe", - NamedExecutable.BackendTool => Platform.IsClientWindows ? "Duplicati.CommandLine.BackendTool.exe" : "duplicati-backend-tool", - NamedExecutable.RecoveryTool => Platform.IsClientWindows ? "Duplicati.CommandLine.RecoveryTool.exe" : "duplicati-recovery-tool", - NamedExecutable.BackendTester => Platform.IsClientWindows ? "Duplicati.CommandLine.BackendTester.exe" : "duplicati-backend-tester", - NamedExecutable.SharpAESCrypt => Platform.IsClientWindows ? "Duplicati.CommandLine.SharpAESCrypt.exe" : "duplicati-aescrypt", - NamedExecutable.Snapshots => Platform.IsClientWindows ? "Duplicati.CommandLine.Snapshots.exe" : "duplicati-snapshots", - NamedExecutable.ConfigurationImporter => Platform.IsClientWindows ? "Duplicati.CommandLine.ConfigurationImporter.exe" : "duplicati-configuration-importer", + NamedExecutable.BackendTool => OperatingSystem.IsWindows() ? "Duplicati.CommandLine.BackendTool.exe" : "duplicati-backend-tool", + NamedExecutable.RecoveryTool => OperatingSystem.IsWindows() ? "Duplicati.CommandLine.RecoveryTool.exe" : "duplicati-recovery-tool", + NamedExecutable.BackendTester => OperatingSystem.IsWindows() ? "Duplicati.CommandLine.BackendTester.exe" : "duplicati-backend-tester", + NamedExecutable.SharpAESCrypt => OperatingSystem.IsWindows() ? "Duplicati.CommandLine.SharpAESCrypt.exe" : "duplicati-aescrypt", + NamedExecutable.Snapshots => OperatingSystem.IsWindows() ? "Duplicati.CommandLine.Snapshots.exe" : "duplicati-snapshots", + NamedExecutable.ConfigurationImporter => OperatingSystem.IsWindows() ? "Duplicati.CommandLine.ConfigurationImporter.exe" : "duplicati-configuration-importer", _ => throw new ArgumentException($"Named executable not known: {exe}", nameof(exe)) }; diff --git a/Duplicati/Library/AutoUpdater/UpdaterManager.cs b/Duplicati/Library/AutoUpdater/UpdaterManager.cs index 06b918b50..9d32af8bd 100644 --- a/Duplicati/Library/AutoUpdater/UpdaterManager.cs +++ b/Duplicati/Library/AutoUpdater/UpdaterManager.cs @@ -118,7 +118,7 @@ namespace Duplicati.Library.AutoUpdater { // OS specific folders for probing var candidates = new List(); - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) { candidates.Add(System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), APPNAME)); candidates.Add(System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), APPNAME)); @@ -128,7 +128,7 @@ namespace Duplicati.Library.AutoUpdater candidates.Add(System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), APPNAME)); } - if (Platform.IsClientOSX) + if (OperatingSystem.IsMacOS()) candidates.Add(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Library", "Application Support", APPNAME)); // Find the first writeable directory in the list diff --git a/Duplicati/Library/Backend/File/FileBackend.cs b/Duplicati/Library/Backend/File/FileBackend.cs index 4238a411b..745e3322c 100644 --- a/Duplicati/Library/Backend/File/FileBackend.cs +++ b/Duplicati/Library/Backend/File/FileBackend.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; +using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -83,7 +84,7 @@ namespace Duplicati.Library.Backend paths.AddRange(options[OPTION_ALTERNATE_PATHS].Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries)); //On windows we expand the drive letter * to all drives - if (!Platform.IsClientPosix) + if (!OperatingSystem.IsWindows()) { System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives(); @@ -300,7 +301,7 @@ namespace Duplicati.Library.Backend private System.IO.DriveInfo GetDrive() { string root; - if (Platform.IsClientPosix) + if (OperatingSystem.IsWindows()) { string path = Util.AppendDirSeparator(systemIO.PathGetFullPath(m_path)); root = "/"; @@ -319,7 +320,7 @@ namespace Duplicati.Library.Backend // On Windows, DriveInfo is only valid for lettered drives. (e.g., not for UNC paths and shares) // So only attempt to get it if we aren't on Windows or if the root starts with a letter. - if (!Platform.IsClientWindows || (root.Length > 0 && char.IsLetter(root[0]))) + if (!OperatingSystem.IsWindows() || (root.Length > 0 && char.IsLetter(root[0]))) { try { @@ -349,7 +350,7 @@ namespace Duplicati.Library.Backend } } - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) { // If we can't get the DriveInfo on Windows, fallback to GetFreeDiskSpaceEx // https://stackoverflow.com/questions/2050343/programmatically-determining-space-available-from-unc-path @@ -380,6 +381,7 @@ namespace Duplicati.Library.Backend /// Directory /// Quota info [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + [SupportedOSPlatform("windows")] public static QuotaInfo GetDiskFreeSpace(string directory) { ulong available; @@ -394,6 +396,7 @@ namespace Duplicati.Library.Backend } } + [SupportedOSPlatform("windows")] private static class WindowsDriveHelper { [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] diff --git a/Duplicati/Library/Common/Platform/Platform.cs b/Duplicati/Library/Common/Platform/Platform.cs index a2bbc2709..9dca9bd25 100644 --- a/Duplicati/Library/Common/Platform/Platform.cs +++ b/Duplicati/Library/Common/Platform/Platform.cs @@ -27,25 +27,30 @@ namespace Duplicati.Library.Common /// /// Gets or sets a value indicating if the client is Linux/Unix based /// + [Obsolete("Use OperatingSystem.IsXXX instead")] public static readonly bool IsClientPosix; /// /// Gets a value indicating if the client is Windows based /// + [Obsolete("Use OperatingSystem.IsXXX instead")] public static readonly bool IsClientWindows; /// /// Gets or sets a value indicating if the client is running OSX /// + [Obsolete("Use OperatingSystem.IsXXX instead")] public static readonly bool IsClientOSX; static Platform() { +#pragma warning disable CS0618 // Obsolete IsClientPosix = Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX; IsClientWindows = !IsClientPosix; IsClientOSX = IsClientPosix && "Darwin".Equals(_RetrieveUname(false)); +#pragma warning restore CS0618 // Obsolete } /// @@ -55,8 +60,10 @@ namespace Duplicati.Library.Common { get { +#pragma warning disable CS0618 // Obsolete if (!IsClientPosix) return null; +#pragma warning restore CS0618 // Obsolete return _RetrieveUname(true); diff --git a/Duplicati/Library/Main/Database/LocalBugReportDatabase.cs b/Duplicati/Library/Main/Database/LocalBugReportDatabase.cs index 5bfb87904..c291d1d64 100644 --- a/Duplicati/Library/Main/Database/LocalBugReportDatabase.cs +++ b/Duplicati/Library/Main/Database/LocalBugReportDatabase.cs @@ -54,7 +54,7 @@ namespace Duplicati.Library.Main.Database upcmd.Transaction = tr; upcmd.ExecuteNonQuery(string.Format(@"CREATE TEMPORARY TABLE ""{0}"" (""ID"" INTEGER PRIMARY KEY, ""RealPath"" TEXT NOT NULL, ""Obfuscated"" TEXT NULL)", tablename)); upcmd.ExecuteNonQuery(string.Format(@"INSERT INTO ""{0}"" (""RealPath"") SELECT DISTINCT ""Path"" FROM ""File"" ORDER BY ""Path"" ", tablename)); - upcmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Obfuscated"" = ? || length(""RealPath"") || ? || ""ID"" || (CASE WHEN substr(""RealPath"", length(""RealPath"")) = ? THEN ? ELSE ? END) ", tablename), Platform.IsClientPosix ? "/" : "X:\\", Util.DirectorySeparatorString, Util.DirectorySeparatorString, Util.DirectorySeparatorString, ".bin"); + upcmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Obfuscated"" = ? || length(""RealPath"") || ? || ""ID"" || (CASE WHEN substr(""RealPath"", length(""RealPath"")) = ? THEN ? ELSE ? END) ", tablename), !OperatingSystem.IsWindows() ? "/" : "X:\\", Util.DirectorySeparatorString, Util.DirectorySeparatorString, Util.DirectorySeparatorString, ".bin"); /*long id = 1; using(var rd = cmd.ExecuteReader(string.Format(@"SELECT ""RealPath"", ""Obfuscated"" FROM ""{0}"" ", tablename))) diff --git a/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs b/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs index bdfe2674b..3da07a950 100644 --- a/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs +++ b/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs @@ -413,14 +413,14 @@ namespace Duplicati.Library.Main.Database // defaults when restoring cross OS, e.g. backup on Linux, restore on Windows //This is mostly meaningless, and the user really should use --restore-path - if (Platform.IsClientPosix && dirsep == "\\") + if ((OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) && dirsep == "\\") { // For Win -> Linux, we remove the colon from the drive letter, and use the drive letter as root folder cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = CASE WHEN SUBSTR(""Path"", 2, 1) == ':' THEN '\\' || SUBSTR(""Path"", 1, 1) || SUBSTR(""Path"", 3) ELSE ""Path"" END", m_tempfiletable)); cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = CASE WHEN SUBSTR(""Path"", 1, 2) == '\\' THEN '\\' || SUBSTR(""Path"", 2) ELSE ""Path"" END", m_tempfiletable)); } - else if (Platform.IsClientWindows && dirsep == "/") + else if (OperatingSystem.IsWindows() && dirsep == "/") { // For Linux -> Win, we use the temporary folder's drive as the root path cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = CASE WHEN SUBSTR(""Path"", 1, 1) == '/' THEN ? || SUBSTR(""Path"", 2) ELSE ""Path"" END", m_tempfiletable), Util.AppendDirSeparator(System.IO.Path.GetPathRoot(Library.Utility.TempFolder.SystemTempPath)).Replace("\\", "/")); @@ -451,10 +451,10 @@ namespace Duplicati.Library.Main.Database } // Cross-os path remapping support - if (Platform.IsClientPosix && dirsep == "\\") + if ((OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) && dirsep == "\\") // For Win paths on Linux cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""TargetPath"" = REPLACE(""TargetPath"", '\', '/')", m_tempfiletable)); - else if (Platform.IsClientWindows && dirsep == "/") + else if (OperatingSystem.IsWindows() && dirsep == "/") // For Linux paths on Windows cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""TargetPath"" = REPLACE(REPLACE(""TargetPath"", '\', '_'), '/', '\')", m_tempfiletable)); diff --git a/Duplicati/Library/Main/DatabaseLocator.cs b/Duplicati/Library/Main/DatabaseLocator.cs index b0674913f..124add6b4 100644 --- a/Duplicati/Library/Main/DatabaseLocator.cs +++ b/Duplicati/Library/Main/DatabaseLocator.cs @@ -63,7 +63,7 @@ namespace Duplicati.Library.Main var folder = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Duplicati"); - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) { var newlocation = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Duplicati"); diff --git a/Duplicati/Library/Main/Operation/BackupHandler.cs b/Duplicati/Library/Main/Operation/BackupHandler.cs index a27635f0e..a31306aae 100644 --- a/Duplicati/Library/Main/Operation/BackupHandler.cs +++ b/Duplicati/Library/Main/Operation/BackupHandler.cs @@ -233,6 +233,7 @@ namespace Duplicati.Library.Main.Operation // append files from previous fileset, unless part of modifiedSources, which we've just scanned await database.AppendFilesFromPreviousSetWithPredicateAsync((path, fileSize) => { + // TODO: This is technically unsupported, but the method itself works cross-platform if (journalService.IsPathEnumerated(path)) return true; diff --git a/Duplicati/Library/Modules/Builtin/ConsolePasswordInput.cs b/Duplicati/Library/Modules/Builtin/ConsolePasswordInput.cs index bdef9e9b1..405468e0e 100644 --- a/Duplicati/Library/Modules/Builtin/ConsolePasswordInput.cs +++ b/Duplicati/Library/Modules/Builtin/ConsolePasswordInput.cs @@ -85,7 +85,7 @@ namespace Duplicati.Library.Modules.Builtin catch (InvalidOperationException) { // Handle redirect issues on Windows only - if (!Platform.IsClientWindows) + if (!OperatingSystem.IsWindows()) throw; commandlineOptions["passphrase"] = ReadPassphraseFromStdin(confirm); diff --git a/Duplicati/Library/Modules/Builtin/HyperVOptions.cs b/Duplicati/Library/Modules/Builtin/HyperVOptions.cs index 281e3a68e..7f63be226 100644 --- a/Duplicati/Library/Modules/Builtin/HyperVOptions.cs +++ b/Duplicati/Library/Modules/Builtin/HyperVOptions.cs @@ -57,7 +57,7 @@ namespace Duplicati.Library.Modules.Builtin public bool LoadAsDefault { - get { return Platform.IsClientWindows; } + get { return OperatingSystem.IsWindows(); } } public IList SupportedCommands @@ -218,7 +218,7 @@ namespace Duplicati.Library.Modules.Builtin public bool ContainFilesForBackup(string[] paths) { - if (paths == null || !Platform.IsClientWindows) + if (paths == null || !OperatingSystem.IsWindows()) return false; return paths.Where(x => !string.IsNullOrWhiteSpace(x)).Any(x => x.Equals(m_HyperVPathAllRegExp, StringComparison.OrdinalIgnoreCase) || Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)); diff --git a/Duplicati/Library/Modules/Builtin/MSSQLOptions.cs b/Duplicati/Library/Modules/Builtin/MSSQLOptions.cs index 9d4d12ea5..fa637843c 100644 --- a/Duplicati/Library/Modules/Builtin/MSSQLOptions.cs +++ b/Duplicati/Library/Modules/Builtin/MSSQLOptions.cs @@ -58,7 +58,7 @@ namespace Duplicati.Library.Modules.Builtin public bool LoadAsDefault { - get { return Platform.IsClientWindows; } + get { return OperatingSystem.IsWindows(); } } public IList SupportedCommands @@ -216,7 +216,7 @@ namespace Duplicati.Library.Modules.Builtin public bool ContainFilesForBackup(string[] paths) { - if (paths == null || !Platform.IsClientWindows) + if (paths == null || !OperatingSystem.IsWindows()) return false; return paths.Where(x => !string.IsNullOrWhiteSpace(x)).Any(x => x.Equals(m_MSSQLPathAllRegExp, StringComparison.OrdinalIgnoreCase) || Regex.IsMatch(x, m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)); diff --git a/Duplicati/Library/Snapshots/HyperVUtility.cs b/Duplicati/Library/Snapshots/HyperVUtility.cs index 32a686bb9..ca70893b7 100644 --- a/Duplicati/Library/Snapshots/HyperVUtility.cs +++ b/Duplicati/Library/Snapshots/HyperVUtility.cs @@ -116,13 +116,14 @@ namespace Duplicati.Library.Snapshots { Guests = new List(); - if (!Platform.IsClientWindows) + if (!OperatingSystem.IsWindows()) { IsHyperVInstalled = false; IsVSSWriterSupported = false; return; } + // TODO: Replace with OperatingSystem.IsWindowsVersionAtLeast(6,2) if that is correct //Set the namespace depending off host OS _wmiv2Namespace = Environment.OSVersion.Version.Major > 6 || (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2); diff --git a/Duplicati/Library/Snapshots/MSSQLUtility.cs b/Duplicati/Library/Snapshots/MSSQLUtility.cs index 78a5ecee5..416fe2bd8 100644 --- a/Duplicati/Library/Snapshots/MSSQLUtility.cs +++ b/Duplicati/Library/Snapshots/MSSQLUtility.cs @@ -107,7 +107,7 @@ namespace Duplicati.Library.Snapshots { m_DBs = new List(); - if (!Platform.IsClientWindows) + if (!OperatingSystem.IsWindows()) { IsMSSQLInstalled = false; return; diff --git a/Duplicati/Library/Snapshots/Program.cs b/Duplicati/Library/Snapshots/Program.cs index 45dcef867..57194cd22 100644 --- a/Duplicati/Library/Snapshots/Program.cs +++ b/Duplicati/Library/Snapshots/Program.cs @@ -107,7 +107,7 @@ Where is the folder where files will be locked/created etc"); } Console.WriteLine("Creating snapshot for folder: {0}", args[0]); - Console.WriteLine("If this fails, try to run as " + (Platform.IsClientPosix ? "root" : "Administrator")); + Console.WriteLine("If this fails, try to run as " + ((OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) ? "root" : "Administrator")); using (ISnapshotService snapshot = SnapshotUtility.CreateSnapshot(new[] { args[0] }, options)) { Console.WriteLine("Attempting to read locked file via snapshot"); diff --git a/Duplicati/Library/Snapshots/USNJournal.cs b/Duplicati/Library/Snapshots/USNJournal.cs index d0c7e9d9d..087567f6d 100644 --- a/Duplicati/Library/Snapshots/USNJournal.cs +++ b/Duplicati/Library/Snapshots/USNJournal.cs @@ -102,9 +102,6 @@ namespace Duplicati.Library.Snapshots /// The root volume where the USN lookup is performed internal USNJournal(string volumeRoot) { - if (Platform.IsClientPosix) - throw new Interface.UserInformationException(Strings.USNHelper.LinuxNotSupportedError, "UsnOnLinuxNotSupported"); - m_volume = Util.AppendDirSeparator(volumeRoot); try diff --git a/Duplicati/Library/UsageReporter/OSInfoHelper.cs b/Duplicati/Library/UsageReporter/OSInfoHelper.cs index 366bc2264..0035061b1 100644 --- a/Duplicati/Library/UsageReporter/OSInfoHelper.cs +++ b/Duplicati/Library/UsageReporter/OSInfoHelper.cs @@ -77,11 +77,11 @@ namespace Duplicati.Library.UsageReporter { get { - if (!Platform.IsClientPosix) + if (!(OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())) { return Environment.OSVersion.ToString(); } - else if (Platform.IsClientOSX) + else if (OperatingSystem.IsMacOS()) { var m = RunProgramAndReadOutput("sw_vers", null); if (m != null) diff --git a/Duplicati/Library/Utility/FilterGroups.cs b/Duplicati/Library/Utility/FilterGroups.cs index 30031598c..8b8288284 100644 --- a/Duplicati/Library/Utility/FilterGroups.cs +++ b/Duplicati/Library/Utility/FilterGroups.cs @@ -237,11 +237,11 @@ namespace Duplicati.Library.Utility { IEnumerable osFilters; - if (Platform.IsClientOSX) + if (OperatingSystem.IsMacOS()) osFilters = CreateOSXFilters(group); - else if (Platform.IsClientPosix) + else if (OperatingSystem.IsLinux()) osFilters = CreateLinuxFilters(group); - else if (Platform.IsClientWindows) + else if (OperatingSystem.IsWindows()) osFilters = CreateWindowsFilters(group); else throw new ArgumentException("Unknown operating system?"); @@ -641,7 +641,7 @@ namespace Duplicati.Library.Utility private static IEnumerable GetOSXExcludeFiles() { var res = new List(); - if (Platform.IsClientOSX) + if (OperatingSystem.IsMacOS()) { try { diff --git a/Duplicati/Library/Utility/SslCertificateValidator.cs b/Duplicati/Library/Utility/SslCertificateValidator.cs index 8b4131ee9..2f113ef7f 100644 --- a/Duplicati/Library/Utility/SslCertificateValidator.cs +++ b/Duplicati/Library/Utility/SslCertificateValidator.cs @@ -38,7 +38,7 @@ namespace Duplicati.Library.Utility public SslPolicyErrors SslError { get { return m_errors; } } public InvalidCertificateException(string certificate, SslPolicyErrors error) - : base(Strings.SslCertificateValidator.VerifyCertificateException(error, certificate) + (Platform.IsClientPosix ? Strings.SslCertificateValidator.MonoHelpSSL : "")) + : base(Strings.SslCertificateValidator.VerifyCertificateException(error, certificate) + (!OperatingSystem.IsWindows() ? Strings.SslCertificateValidator.MonoHelpSSL : "")) { m_certificate = certificate; m_errors = error; diff --git a/Duplicati/Library/Utility/UrlUtility.cs b/Duplicati/Library/Utility/UrlUtility.cs index fb527b0ac..7d1c82204 100644 --- a/Duplicati/Library/Utility/UrlUtility.cs +++ b/Duplicati/Library/Utility/UrlUtility.cs @@ -21,6 +21,7 @@ using System; using System.Collections.Generic; +using System.Runtime.Versioning; using System.Text; using Duplicati.Library.Common; @@ -57,7 +58,7 @@ namespace Duplicati.Library.Utility browserprogram = SystemBrowser; //Fallback is to just show the window in a browser - if (Platform.IsClientOSX) + if (OperatingSystem.IsMacOS()) { try { @@ -70,7 +71,7 @@ namespace Duplicati.Library.Utility ErrorHandler(string.Format("Unable to open a browser window, please manually visit: \r\n{0}", url)); } } - else if (Platform.IsClientPosix) + else if (OperatingSystem.IsLinux()) { try { @@ -93,16 +94,21 @@ namespace Duplicati.Library.Utility ErrorHandler(string.Format("Unable to open a browser window, please manually visit: \r\n{0}", url)); } } - else + else if (OperatingSystem.IsWindows()) { OpenUrlWindows(url, browserprogram); } + else + { + throw new NotSupportedException("Unsupported Operating System"); + } } /// /// Opens the given URL in a browser /// /// The url to open, must start with http:// or https:// + [SupportedOSPlatform("windows")] private static void OpenUrlWindows(string url, string browserprogram) { if (string.IsNullOrWhiteSpace(browserprogram)) diff --git a/Duplicati/Library/Utility/Utility.cs b/Duplicati/Library/Utility/Utility.cs index 2ba92d0e2..6f53d5c2b 100644 --- a/Duplicati/Library/Utility/Utility.cs +++ b/Duplicati/Library/Utility/Utility.cs @@ -460,13 +460,13 @@ namespace Duplicati.Library.Utility if (last == -1 || last == 0 && len == 0) return null; - if (last == 0 && !Platform.IsClientWindows) + if (last == 0 && !OperatingSystem.IsWindows()) return Util.DirectorySeparatorString; var parent = path.Substring(0, last); if (forceTrailingDirectorySeparator || - Platform.IsClientWindows && parent.Length == 2 && parent[1] == ':' && char.IsLetter(parent[0])) + OperatingSystem.IsWindows() && parent.Length == 2 && parent[1] == ':' && char.IsLetter(parent[0])) { parent += Path.DirectorySeparatorChar; } @@ -874,7 +874,7 @@ namespace Duplicati.Library.Utility // TODO: This should probably be determined by filesystem rather than OS, // OSX can actually have the disks formatted as Case Sensitive, but insensitive is default - CachedIsFSCaseSensitive = ParseBool(str, () => Platform.IsClientPosix && !Platform.IsClientOSX); + CachedIsFSCaseSensitive = ParseBool(str, () => OperatingSystem.IsLinux()); } return CachedIsFSCaseSensitive.Value; @@ -894,7 +894,7 @@ namespace Duplicati.Library.Utility /// /// The path to the users home directory /// - public static readonly string HOME_PATH = Environment.GetFolderPath(Platform.IsClientPosix ? Environment.SpecialFolder.Personal : Environment.SpecialFolder.UserProfile); + public static readonly string HOME_PATH = Environment.GetFolderPath(!OperatingSystem.IsWindows() ? Environment.SpecialFolder.Personal : Environment.SpecialFolder.UserProfile); /// /// Regexp for matching environment variables on Windows (%VAR%) @@ -1392,7 +1392,7 @@ namespace Duplicati.Library.Utility if (string.IsNullOrWhiteSpace(arg)) return arg; - if (!Platform.IsClientWindows) + if (!OperatingSystem.IsWindows()) { // We could consider using single quotes that prevents all expansions //if (!allowEnvExpansion) diff --git a/Duplicati/Library/Utility/WinTools.cs b/Duplicati/Library/Utility/WinTools.cs index 4e7c3f932..3b2f44b64 100644 --- a/Duplicati/Library/Utility/WinTools.cs +++ b/Duplicati/Library/Utility/WinTools.cs @@ -19,6 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; using System.Runtime.Versioning; using Duplicati.Library.Common; @@ -29,7 +30,7 @@ namespace Duplicati.Library.Utility { public static string GetWindowsGpgExePath() { - if (!Platform.IsClientWindows) + if (!OperatingSystem.IsWindows()) { return null; } diff --git a/Duplicati/Server/Program.cs b/Duplicati/Server/Program.cs index f9214345b..51a4d3379 100644 --- a/Duplicati/Server/Program.cs +++ b/Duplicati/Server/Program.cs @@ -222,7 +222,7 @@ namespace Duplicati.Server { //If we are on Windows, append the bundled "win-tools" programs to the search path //We add it last, to allow the user to override with other versions - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) { Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + @@ -800,7 +800,7 @@ namespace Duplicati.Server }); - if (!Platform.IsClientPosix) + if (!(OperatingSystem.IsMacOS()|| OperatingSystem.IsLinux())) lst.Add(new Duplicati.Library.Interface.CommandLineArgument("server-encryption-key", Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Password, Strings.Program.ServerencryptionkeyShort, Strings.Program.ServerencryptionkeyLong(DB_KEY_ENV_NAME, "unencrypted-database"), Library.AutoUpdater.AutoUpdateSettings.AppName + "_Key_42", null, null, "Database encryption is no longer supported, this setting can only be used to decrypt the database")); return lst.ToArray(); diff --git a/Duplicati/Server/SingleInstance.cs b/Duplicati/Server/SingleInstance.cs index 72ad443ee..0fb9b38ae 100644 --- a/Duplicati/Server/SingleInstance.cs +++ b/Duplicati/Server/SingleInstance.cs @@ -191,7 +191,7 @@ namespace Duplicati.Server //HACK: the unix file lock does not allow us to read the file length when the file is locked if (new System.IO.FileInfo(m_lockfilename).Length == 0) - if (!Platform.IsClientPosix) + if (!(OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())) throw new Exception("The file was locked, but had no data"); //Notify the other process that we have started @@ -241,7 +241,7 @@ namespace Duplicati.Server // needs a little time to create+lock the file. This is not really a fix, but an // ugly workaround. This functionality is only used to allow a new instance to signal // the running instance, so errors here would only affect that functionality - if (Platform.IsClientPosix) + if ((OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())) System.Threading.Thread.Sleep(1000); do diff --git a/Duplicati/UnitTest/BasicSetupHelper.cs b/Duplicati/UnitTest/BasicSetupHelper.cs index a8be31209..cb6c44b90 100644 --- a/Duplicati/UnitTest/BasicSetupHelper.cs +++ b/Duplicati/UnitTest/BasicSetupHelper.cs @@ -203,7 +203,7 @@ namespace Duplicati.UnitTest /// protected static void ZipFileExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName) { - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) { // Handle long paths under Windows by extracting to a // temporary file and moving the resulting file to the diff --git a/Duplicati/UnitTest/IOTests.cs b/Duplicati/UnitTest/IOTests.cs index 71732eaf7..0a2fc4749 100644 --- a/Duplicati/UnitTest/IOTests.cs +++ b/Duplicati/UnitTest/IOTests.cs @@ -26,6 +26,7 @@ using Duplicati.Library.Common.IO; using Duplicati.Library.Utility; using Duplicati.Library.Common; using System.Collections.Generic; +using System; namespace Duplicati.UnitTest { @@ -42,7 +43,7 @@ namespace Duplicati.UnitTest [Test] public void TestGetPathRootWithLongPath() { - var pathRoot = Platform.IsClientWindows ? "C:\\" : "/"; + var pathRoot = OperatingSystem.IsWindows() ? "C:\\" : "/"; var root = SystemIO.IO_OS.GetPathRoot(LongPath(pathRoot)); Assert.AreEqual(pathRoot, root); @@ -51,7 +52,7 @@ namespace Duplicati.UnitTest [Test] public void TestUncBehaviourOfGetPathRoot() { - if (!System.OperatingSystem.IsWindows()) + if (!OperatingSystem.IsWindows()) { return; } @@ -74,7 +75,7 @@ namespace Duplicati.UnitTest [Test] public void TestGetFilesWhenDirectoryDoesNotExist() { - var pathRoot = Platform.IsClientWindows ? "C:\\" : "/"; + var pathRoot = OperatingSystem.IsWindows() ? "C:\\" : "/"; var longPath = LongPath(pathRoot); if (SystemIO.IO_OS.DirectoryExists(longPath)) @@ -89,7 +90,7 @@ namespace Duplicati.UnitTest [Test] public void TestGetDirectoriesWhenDirectoryDoesNotExist() { - var pathRoot = Platform.IsClientWindows ? "C:\\" : "/"; + var pathRoot = OperatingSystem.IsWindows() ? "C:\\" : "/"; var longPath = LongPath(pathRoot); if (SystemIO.IO_OS.DirectoryExists(longPath)) @@ -104,7 +105,7 @@ namespace Duplicati.UnitTest [Test] public void TestAddExtendedDevicePathPrefixInWindowsClient() { - if (!System.OperatingSystem.IsWindows()) + if (!OperatingSystem.IsWindows()) { return; } @@ -212,7 +213,7 @@ namespace Duplicati.UnitTest [Test] public void TestPathGetFullPathInWindowsClient() { - if (!System.OperatingSystem.IsWindows()) + if (!OperatingSystem.IsWindows()) { return; } diff --git a/Duplicati/UnitTest/ProblematicPathTests.cs b/Duplicati/UnitTest/ProblematicPathTests.cs index a0baab6eb..c96ecfd23 100644 --- a/Duplicati/UnitTest/ProblematicPathTests.cs +++ b/Duplicati/UnitTest/ProblematicPathTests.cs @@ -18,6 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -50,7 +51,7 @@ namespace Duplicati.UnitTest const string asterisk = "*"; string dirWithAsterisk = Path.Combine(this.DATAFOLDER, asterisk); // Windows does not support literal asterisks in paths. - if (!Platform.IsClientWindows) + if (!OperatingSystem.IsWindows()) { SystemIO.IO_OS.DirectoryCreate(dirWithAsterisk); TestUtils.WriteFile(SystemIO.IO_OS.PathCombine(dirWithAsterisk, file), new byte[] {0}); @@ -62,7 +63,7 @@ namespace Duplicati.UnitTest const string questionMark = "?"; string dirWithQuestionMark = Path.Combine(this.DATAFOLDER, questionMark); // Windows does not support literal question marks in paths. - if (!Platform.IsClientWindows) + if (!OperatingSystem.IsWindows()) { SystemIO.IO_OS.DirectoryCreate(dirWithQuestionMark); TestUtils.WriteFile(SystemIO.IO_OS.PathCombine(dirWithQuestionMark, file), new byte[] { 1 }); @@ -280,7 +281,7 @@ namespace Duplicati.UnitTest [TestCase("ends_with_newline\n", true)] public void ProblematicSuffixes(string pathComponent, bool skipOnWindows) { - if (Platform.IsClientWindows && skipOnWindows) + if (OperatingSystem.IsWindows() && skipOnWindows) { return; } diff --git a/Duplicati/UnitTest/RestoreHandlerTests.cs b/Duplicati/UnitTest/RestoreHandlerTests.cs index 307b41e9a..dd64f2228 100644 --- a/Duplicati/UnitTest/RestoreHandlerTests.cs +++ b/Duplicati/UnitTest/RestoreHandlerTests.cs @@ -18,6 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -65,7 +66,7 @@ namespace Duplicati.UnitTest // if it's determined to be an absolute path. string rootString = SystemIO.IO_OS.GetPathRoot(filePath); string newPathPart = filePath.Substring(rootString.Length); - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) { // On Windows, the drive letter is included in the path when the dont-compress-restore-paths option is used. // The drive letter is assumed to be the first character of the path root (e.g., C:\). @@ -80,7 +81,7 @@ namespace Duplicati.UnitTest [Category("RestoreHandler")] public void RestoreInheritanceBreaks() { - if (!Platform.IsClientWindows) + if (!OperatingSystem.IsWindows()) { return; } diff --git a/Duplicati/UnitTest/RunScriptTests.cs b/Duplicati/UnitTest/RunScriptTests.cs index 5cf8571dd..3c74f8e96 100644 --- a/Duplicati/UnitTest/RunScriptTests.cs +++ b/Duplicati/UnitTest/RunScriptTests.cs @@ -222,7 +222,7 @@ namespace Duplicati.UnitTest { string parsedResultFile = Path.Combine(this.RESTOREFOLDER, "result.txt"); List customCommands = new List(); - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) { customCommands.Add($"echo %DUPLICATI__PARSED_RESULT%>\"{parsedResultFile}\""); } @@ -335,7 +335,7 @@ namespace Duplicati.UnitTest private string CreateScript(int exitcode, string stderr = null, string stdout = null, int sleeptime = 0, List customCommands = null) { var id = Guid.NewGuid().ToString("N").Substring(0, 6); - if (Platform.IsClientWindows) + if (OperatingSystem.IsWindows()) { var commands = customCommands ?? new List(); if (!string.IsNullOrWhiteSpace(stdout)) diff --git a/Duplicati/UnitTest/TestUtils.cs b/Duplicati/UnitTest/TestUtils.cs index ce27ec90c..be05077ce 100644 --- a/Duplicati/UnitTest/TestUtils.cs +++ b/Duplicati/UnitTest/TestUtils.cs @@ -253,7 +253,7 @@ namespace Duplicati.UnitTest // macOS seem to like to actually set the time to some value different than what you set by hundreds of milliseconds. // Reading the time right after it is set gives the expected value but when read later it is slightly different. // Maybe a bug in .net? - int granularity = Platform.IsClientOSX ? 2999 : 1; + int granularity = OperatingSystem.IsMacOS() ? 2999 : 1; Assert.That( SystemIO.IO_OS.GetLastWriteTimeUtc(actualFile), Is.EqualTo(SystemIO.IO_OS.GetLastWriteTimeUtc(expectedFile)).Within(granularity).Milliseconds,