Made the database locator and server-database location code the same.
This commit is contained in:
@@ -22,8 +22,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Duplicati.Library.Common;
|
||||
|
||||
namespace Duplicati.Library.Main
|
||||
{
|
||||
@@ -38,10 +36,65 @@ namespace Duplicati.Library.Main
|
||||
public string Username;
|
||||
//public string Passwordhash;
|
||||
public int Port;
|
||||
public string Databasepath;
|
||||
public string Databasepath;
|
||||
public string ParameterFile;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The filename of the file with database configurations
|
||||
/// </summary>
|
||||
private const string CONFIG_FILE = "dbconfig.json";
|
||||
|
||||
/// <summary>
|
||||
/// Finds a default storage folder, using the operating system specific locations.
|
||||
/// The targetfilename is used to detect locations that are used in previous versions.
|
||||
/// If the targetfilename is found in an old location, but not the current, the old location is used.
|
||||
/// </summary>
|
||||
/// <param name="targetfilename">The filename to look for</param>
|
||||
/// <param name="appName">The name of the application</param>
|
||||
/// <returns>The default storage folder</returns>
|
||||
public static string GetDefaultStorageFolder(string targetfilename, string appName = "Duplicati")
|
||||
{
|
||||
//Normal mode uses the systems "(Local) Application Data" folder
|
||||
// %LOCALAPPDATA% on Windows, ~/.config on Linux
|
||||
var folder = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), appName);
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
// Special handling for Windows:
|
||||
// - Older versions use %APPDATA%
|
||||
// - but new versions use %LOCALAPPDATA%
|
||||
var newlocation = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), appName);
|
||||
|
||||
var prevfile = System.IO.Path.Combine(folder, targetfilename);
|
||||
var curfile = System.IO.Path.Combine(newlocation, targetfilename);
|
||||
|
||||
// If the new file exists, we use that
|
||||
// If the new file does not exist, and the old file exists we use the old
|
||||
// Otherwise we use the new location
|
||||
if (System.IO.File.Exists(curfile) || !System.IO.File.Exists(prevfile))
|
||||
folder = newlocation;
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsMacOS())
|
||||
{
|
||||
// Special handling for MacOS:
|
||||
// - Older versions use ~/.config/
|
||||
// - but new versions use ~/Library/Application\ Support/
|
||||
var configfolder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".config", appName);
|
||||
|
||||
var prevfile = System.IO.Path.Combine(configfolder, targetfilename);
|
||||
var curfile = System.IO.Path.Combine(folder, targetfilename);
|
||||
|
||||
// If the old file exists, and not the new file, we use the old
|
||||
// Otherwise we use the new location
|
||||
if (!System.IO.File.Exists(curfile) && System.IO.File.Exists(prevfile))
|
||||
folder = configfolder;
|
||||
}
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
public static string GetDatabasePath(string backend, Options options, bool autoCreate = true, bool anyUsername = false)
|
||||
{
|
||||
if (options == null)
|
||||
@@ -50,40 +103,15 @@ namespace Duplicati.Library.Main
|
||||
if (!string.IsNullOrEmpty(options.Dbpath))
|
||||
return options.Dbpath;
|
||||
|
||||
//Normal mode uses the systems "(Local) Application Data" folder
|
||||
// %LOCALAPPDATA% on Windows, ~/.config on Linux
|
||||
var folder = GetDefaultStorageFolder(CONFIG_FILE);
|
||||
|
||||
// Special handling for Windows:
|
||||
// - Older versions use %APPDATA%
|
||||
// - but new versions use %LOCALAPPDATA%
|
||||
//
|
||||
// If we find a new version, lets use that
|
||||
// otherwise use the older location
|
||||
//
|
||||
|
||||
var folder = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Duplicati");
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
var newlocation = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Duplicati");
|
||||
|
||||
var prevfile = System.IO.Path.Combine(folder, "dbconfig.json");
|
||||
var curfile = System.IO.Path.Combine(newlocation, "dbconfig.json");
|
||||
|
||||
// If the new file exists, we use that
|
||||
// If the new file does not exist, and the old file exists we use the old
|
||||
// Otherwise we use the new location
|
||||
if (System.IO.File.Exists(curfile) || !System.IO.File.Exists(prevfile))
|
||||
folder = newlocation;
|
||||
}
|
||||
|
||||
var file = System.IO.Path.Combine(folder, "dbconfig.json");
|
||||
var file = System.IO.Path.Combine(folder, CONFIG_FILE);
|
||||
List<BackendEntry> configs;
|
||||
if (!System.IO.File.Exists(file))
|
||||
configs = new List<BackendEntry>();
|
||||
else
|
||||
configs = Newtonsoft.Json.JsonConvert.DeserializeObject<List<BackendEntry>>(System.IO.File.ReadAllText(file, System.Text.Encoding.UTF8));
|
||||
|
||||
|
||||
var uri = new Library.Utility.Uri(backend);
|
||||
string server = uri.Host;
|
||||
string path = uri.Path;
|
||||
@@ -91,64 +119,64 @@ namespace Duplicati.Library.Main
|
||||
int port = uri.Port;
|
||||
string username = uri.Username;
|
||||
string prefix = options.Prefix;
|
||||
|
||||
|
||||
if (username == null || uri.Password == null)
|
||||
{
|
||||
var sopts = DynamicLoader.BackendLoader.GetSupportedCommands(backend);
|
||||
var ropts = new Dictionary<string, string>(options.RawOptions);
|
||||
foreach(var k in uri.QueryParameters.AllKeys)
|
||||
foreach (var k in uri.QueryParameters.AllKeys)
|
||||
ropts[k] = uri.QueryParameters[k];
|
||||
|
||||
|
||||
if (sopts != null)
|
||||
{
|
||||
foreach(var o in sopts)
|
||||
foreach (var o in sopts)
|
||||
{
|
||||
if (username == null && o.Aliases != null && o.Aliases.Contains("auth-username", StringComparer.OrdinalIgnoreCase) && ropts.ContainsKey(o.Name))
|
||||
username = ropts[o.Name];
|
||||
}
|
||||
|
||||
foreach(var o in sopts)
|
||||
|
||||
foreach (var o in sopts)
|
||||
{
|
||||
if (username == null && o.Name.Equals("auth-username", StringComparison.OrdinalIgnoreCase) && ropts.ContainsKey("auth-username"))
|
||||
username = ropts["auth-username"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Now find the one that matches :)
|
||||
var matches = (from n in configs
|
||||
where
|
||||
n.Type == type &&
|
||||
//n.Passwordhash == password &&
|
||||
n.Username == username &&
|
||||
n.Port == port &&
|
||||
n.Server == server &&
|
||||
n.Path == path &&
|
||||
n.Prefix == prefix
|
||||
select n).ToList();
|
||||
|
||||
where
|
||||
n.Type == type &&
|
||||
//n.Passwordhash == password &&
|
||||
n.Username == username &&
|
||||
n.Port == port &&
|
||||
n.Server == server &&
|
||||
n.Path == path &&
|
||||
n.Prefix == prefix
|
||||
select n).ToList();
|
||||
|
||||
if (matches.Count > 1)
|
||||
throw new Duplicati.Library.Interface.UserInformationException(string.Format("Multiple sources found for: {0}", backend), "MultipleLocalDatabaseSourcesFound");
|
||||
|
||||
|
||||
// Re-select
|
||||
if (matches.Count == 0 && anyUsername && string.IsNullOrEmpty(username))
|
||||
{
|
||||
matches = (from n in configs
|
||||
where
|
||||
n.Type == type &&
|
||||
n.Port == port &&
|
||||
n.Server == server &&
|
||||
n.Path == path &&
|
||||
n.Prefix == prefix
|
||||
select n).ToList();
|
||||
|
||||
where
|
||||
n.Type == type &&
|
||||
n.Port == port &&
|
||||
n.Server == server &&
|
||||
n.Path == path &&
|
||||
n.Prefix == prefix
|
||||
select n).ToList();
|
||||
|
||||
if (matches.Count > 1)
|
||||
throw new Duplicati.Library.Interface.UserInformationException(String.Format("Multiple sources found for \"{0}\", try supplying --{1}", backend, "auth-username"), "MultipleLocalDatabaseSourcesFound");
|
||||
}
|
||||
|
||||
|
||||
if (matches.Count == 0 && !autoCreate)
|
||||
return null;
|
||||
|
||||
|
||||
if (matches.Count == 0)
|
||||
{
|
||||
var backupname = options.BackupName;
|
||||
@@ -156,20 +184,21 @@ namespace Duplicati.Library.Main
|
||||
backupname = GenerateRandomName();
|
||||
else
|
||||
{
|
||||
foreach(var c in System.IO.Path.GetInvalidFileNameChars())
|
||||
foreach (var c in System.IO.Path.GetInvalidFileNameChars())
|
||||
backupname = backupname.Replace(c.ToString(), "");
|
||||
}
|
||||
|
||||
|
||||
var newpath = System.IO.Path.Combine(folder, backupname + ".sqlite");
|
||||
int max_tries = 100;
|
||||
while (System.IO.File.Exists(newpath) && max_tries-- > 0)
|
||||
newpath = System.IO.Path.Combine(folder, GenerateRandomName());
|
||||
|
||||
|
||||
if (System.IO.File.Exists(newpath))
|
||||
throw new Duplicati.Library.Interface.UserInformationException("Unable to find a unique name for the database, please use --dbpath", "CannotCreateRandomName");
|
||||
|
||||
|
||||
//Create a new one, add it to the list, and save it
|
||||
configs.Add(new BackendEntry() {
|
||||
configs.Add(new BackendEntry()
|
||||
{
|
||||
Type = type,
|
||||
Server = server,
|
||||
Path = path,
|
||||
@@ -177,7 +206,7 @@ namespace Duplicati.Library.Main
|
||||
Username = username,
|
||||
//Passwordhash = password,
|
||||
Port = port,
|
||||
Databasepath = newpath,
|
||||
Databasepath = newpath,
|
||||
ParameterFile = null
|
||||
});
|
||||
|
||||
@@ -187,16 +216,16 @@ namespace Duplicati.Library.Main
|
||||
var settings = new Newtonsoft.Json.JsonSerializerSettings();
|
||||
settings.Formatting = Newtonsoft.Json.Formatting.Indented;
|
||||
System.IO.File.WriteAllText(file, Newtonsoft.Json.JsonConvert.SerializeObject(configs, settings), System.Text.Encoding.UTF8);
|
||||
|
||||
|
||||
return newpath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return matches[0].Databasepath;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static string GenerateRandomName()
|
||||
{
|
||||
var rnd = new Random();
|
||||
@@ -210,11 +239,7 @@ namespace Duplicati.Library.Main
|
||||
|
||||
public static bool IsDatabasePathInUse(string path)
|
||||
{
|
||||
var folder = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Duplicati");
|
||||
if (!System.IO.Directory.Exists(folder))
|
||||
return false;
|
||||
|
||||
var file = System.IO.Path.Combine(folder, "dbconfig.json");
|
||||
var file = System.IO.Path.Combine(GetDefaultStorageFolder(CONFIG_FILE), CONFIG_FILE);
|
||||
if (!System.IO.File.Exists(file))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Duplicati.Library.Common.IO;
|
||||
using Duplicati.Library.Main;
|
||||
using Duplicati.Library.Main.Database;
|
||||
using Duplicati.Library.RestAPI;
|
||||
using Duplicati.Server.Database;
|
||||
@@ -622,50 +623,7 @@ namespace Duplicati.Server
|
||||
{
|
||||
//Normal release mode uses the systems "(Local) Application Data" folder
|
||||
// %LOCALAPPDATA% on Windows, ~/.config on Linux, ~/Library/Application\ Support on MacOS
|
||||
|
||||
serverDataFolder = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Library.AutoUpdater.AutoUpdateSettings.AppName);
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
// Special handling for Windows:
|
||||
// - Older versions use %APPDATA%
|
||||
// - but new versions use %LOCALAPPDATA%
|
||||
//
|
||||
// If we find a new version, lets use that
|
||||
// otherwise use the older location
|
||||
|
||||
var localappdata = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Library.AutoUpdater.AutoUpdateSettings.AppName);
|
||||
|
||||
var prefile = System.IO.Path.Combine(serverDataFolder, SERVER_DATABASE_FILENAME);
|
||||
var curfile = System.IO.Path.Combine(localappdata, SERVER_DATABASE_FILENAME);
|
||||
|
||||
// If the new file exists, we use that
|
||||
// If the new file does not exist, and the old file exists we use the old
|
||||
// Otherwise we use the new location
|
||||
if (System.IO.File.Exists(curfile) || !System.IO.File.Exists(prefile))
|
||||
serverDataFolder = localappdata;
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsMacOS())
|
||||
{
|
||||
// Special handling for MacOS:
|
||||
// - Older versions use ~/.config/
|
||||
// - but new versions use ~/Library/Application\ Support/
|
||||
//
|
||||
// If we find a new version, lets use that
|
||||
// otherwise use the older location
|
||||
|
||||
var homefolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
var configfolder = System.IO.Path.Combine(homefolder, ".config", Library.AutoUpdater.AutoUpdateSettings.AppName);
|
||||
|
||||
var prevfile = System.IO.Path.Combine(configfolder, SERVER_DATABASE_FILENAME);
|
||||
var curfile = System.IO.Path.Combine(serverDataFolder, SERVER_DATABASE_FILENAME);
|
||||
|
||||
// If the old file exists and the new does not, we switch back to the old location
|
||||
if (System.IO.File.Exists(prevfile) && !System.IO.File.Exists(curfile))
|
||||
serverDataFolder = configfolder;
|
||||
}
|
||||
|
||||
DataFolder = serverDataFolder;
|
||||
DataFolder = DatabaseLocator.GetDefaultStorageFolder(SERVER_DATABASE_FILENAME, Library.AutoUpdater.AutoUpdateSettings.AppName);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user