public void Move(IFileSystem source, FileSystemPath sourcePath, IFileSystem destination, FileSystemPath destinationPath) { bool isFile; if ((isFile = sourcePath.IsFile) != destinationPath.IsFile) throw new ArgumentException("The specified destination-path is of a different type than the source-path."); if (isFile) { using (var sourceStream = source.OpenFile(sourcePath, FileAccess.Read)) { using (var destinationStream = destination.CreateFile(destinationPath)) { byte[] buffer = new byte[BufferSize]; int readBytes; while ((readBytes = sourceStream.Read(buffer, 0, buffer.Length)) > 0) destinationStream.Write(buffer, 0, readBytes); } } source.Delete(sourcePath); } else { destination.CreateDirectory(destinationPath); foreach (var ep in source.GetEntities(sourcePath).ToArray()) { var destinationEntityPath = ep.IsFile ? destinationPath.AppendFile(ep.EntityName) : destinationPath.AppendDirectory(ep.EntityName); Move(source, ep, destination, destinationEntityPath); } if (!sourcePath.IsRoot) source.Delete(sourcePath); } }
public ICollection <FileSystemPath> GetEntities(FileSystemPath path) { return(GetZipEntries().Select(ToPath).Where(path.IsParentOf) .Select(entryPath => entryPath.ParentPath == path ? entryPath : path.AppendDirectory(entryPath.RemoveParent(path).GetDirectorySegments()[0])) .Distinct() .ToList()); }
public void AppendDirectoryTest() { Directories.All(d => d.AppendDirectory("dir").IsDirectory); Directories.All(d => d.AppendDirectory("dir").EntityName == "dir"); Directories.All(d => d.AppendDirectory("dir").ParentPath == d); EAssert.Throws <InvalidOperationException>(() => fileA.AppendDirectory("dir")); EAssert.Throws <ArgumentException>(() => root.AppendDirectory("dir/dir")); }
public ICollection<FileSystemPath> GetEntities(FileSystemPath path) { return GetZipEntries() .Select(ToPath) .Where(entryPath => path.IsParentOf(entryPath)) .Select(entryPath => entryPath.ParentPath == path ? entryPath : path.AppendDirectory(entryPath.RemoveParent(path).GetDirectorySegments()[0]) ) .Distinct() .ToList(); }
public void Copy(IFileSystem source, FileSystemPath sourcePath, IFileSystem destination, FileSystemPath destinationPath) { var pSource = (PhysicalFileSystem)source; var pDestination = (PhysicalFileSystem)destination; var pSourcePath = pSource.GetPhysicalPath(sourcePath); var pDestinationPath = pDestination.GetPhysicalPath(destinationPath); if (sourcePath.IsFile) System.IO.File.Copy(pSourcePath, pDestinationPath); else { destination.CreateDirectory(destinationPath); foreach(var e in source.GetEntities(sourcePath)) source.Copy(e, destination, e.IsFile ? destinationPath.AppendFile(e.EntityName) : destinationPath.AppendDirectory(e.EntityName)); } }
public void AppendDirectoryTest() { foreach (var d in Directories) { Assert.IsTrue(d.AppendDirectory("dir").IsDirectory); } foreach (var d in Directories) { Assert.IsTrue(d.AppendDirectory("dir").EntityName == "dir"); } foreach (var d in Directories) { Assert.IsTrue(d.AppendDirectory("dir").ParentPath == d); } EAssert.Throws <InvalidOperationException>(() => fileA.AppendDirectory("dir")); EAssert.Throws <ArgumentException>(() => root.AppendDirectory("dir/dir")); }
public void AppendDirectoryTest() { foreach (var d in Directories) { Assert.True(d.AppendDirectory("dir").IsDirectory); } foreach (var d in Directories) { Assert.True(d.AppendDirectory("dir").EntityName == "dir"); } foreach (var d in Directories) { Assert.True(d.AppendDirectory("dir").ParentPath == d); } // ReSharper disable ReturnValueOfPureMethodIsNotUsed EAssert.Throws <InvalidOperationException>(() => _fileA.AppendDirectory("dir")); EAssert.Throws <ArgumentException>(() => _root.AppendDirectory("dir/dir")); // ReSharper restore ReturnValueOfPureMethodIsNotUsed }
public void Run() { string[] arguments = Environment.GetCommandLineArgs(); string key; SettingsData data; if (File.Exists("settings.xml")) { data = SettingsFile.Read("settings.xml"); } else { Console.WriteLine("Can't find settings.xml file - attempting to generate one"); data = GenerateSettings(); SettingsFile.Write(data, "settings.xml"); } if (arguments.Length > 1 && arguments[1] == "fuse") { try { Fuse.LazyUnmount(arguments[2]); key = AESWrapper.GenerateKeyString(ConsoleEx.Password("Key: "), data.salt, data.iterations, data.keySize); using (var mount = Fuse.Mount(arguments[2], new DeDupeFuseFileSystem(key, data))) { Task t = mount.WaitForUnmountAsync(); t.Wait(); } } catch (FuseException fe) { Console.WriteLine($"Fuse throw an exception: {fe}"); Console.WriteLine("Try unmounting the file system by executing:"); Console.WriteLine($"fuser -kM {arguments[2]}"); Console.WriteLine($"sudo umount -f {arguments[2]}"); } } else { string input = ""; FileSystemPath currentDirectory = FileSystemPath.Parse("/"); string[] Scopes = { DriveService.Scope.Drive, DriveService.Scope.DriveFile }; if (arguments.Length > 1) { key = AESWrapper.GenerateKeyString(arguments[1], data.salt, data.iterations, data.keySize); } else { key = AESWrapper.GenerateKeyString(ConsoleEx.Password("Key: "), data.salt, data.iterations, data.keySize); } using (EncryptedTempFile dbfile = new EncryptedTempFile("data.sqlite.enc", key)) { SQLiteDatabase db = new SQLiteDatabase(dbfile.Path); var res = db.GetDataTable("PRAGMA table_info(settings)"); if (res.Rows.Count == 0) { this.setUpDatabase(db); } this.runMigrations(db); dbfile.Flush(); //GDriveFileSystem gdrive = new GDriveFileSystem(Scopes, "DistrubtedDeDupe", dbfile.Path); Log.Instance.Write("log.txt"); DeDupeFileSystem fs = new DeDupeFileSystem(dbfile.Path, key); foreach (KeyValuePair <string, string> kv in data.locations) { fs.AddFileSystem(new DeDupeLocalFileSystem(kv.Value, kv.Key)); } //fs.AddFileSystem(gdrive); string fileName; byte[] fileData; do { if (currentDirectory.Path == "/") { Console.Write($"#:{currentDirectory.Path}> "); } else { Console.Write($"#:{currentDirectory.Path.TrimEnd('/')}> "); } if (arguments.Length > 1) { input = arguments[2]; } else { input = Console.ReadLine(); } switch (input.Split(" ")[0]) { case "stats": long entitySpaceUsed = long.Parse(db.ExecuteScalar("SELECT SUM(size) FROM entities")); long blockSpaceUsed = long.Parse(db.ExecuteScalar("SELECT SUM(size) FROM blocks")); long chunks = long.Parse(db.ExecuteScalar("SELECT count(id) from blocks")); long diffSpace = entitySpaceUsed - blockSpaceUsed; Console.WriteLine($"Space used for entites => {entitySpaceUsed.GetBytesReadable()}"); Console.WriteLine($"Space used for blocks => {blockSpaceUsed.GetBytesReadable()}"); Console.WriteLine($"Space saved => {diffSpace.GetBytesReadable()}"); Console.WriteLine($"Blocks used => {chunks}"); break; case "addstorage": string location = input.Split(" ")[1].Trim(); string name = input.Split(" ")[2].Trim(); data.locations[name] = Path.GetFullPath(location); fs.AddFileSystem(new DeDupeLocalFileSystem(Path.GetFullPath(location), name)); SettingsFile.Write(data, "settings.xml"); break; case "decryptdb": fileName = input.Split(" ")[1].Trim(); //byte[] plain = AESWrapper.DecryptToByte(System.IO.File.ReadAllBytes(dbfile.Path), key); System.IO.File.WriteAllBytes(fileName, System.IO.File.ReadAllBytes(dbfile.Path)); break; case "help": ShowHelp(); break; case "changekey": key = AESWrapper.GenerateKeyString(ConsoleEx.Password("Key: "), data.salt, data.iterations, data.keySize); fs.UpdateKey(key); break; case "generate": data = GenerateSettings(); if (data != null) { SettingsFile.Write(data, "settings.xml"); key = AESWrapper.GenerateKeyString(ConsoleEx.Password("Key: "), data.salt, data.iterations, data.keySize); fs.UpdateKey(key); } break; case "showsettings": Console.WriteLine($"Iterations = {data.iterations}"); Console.WriteLine($"Salt = {data.salt}"); Console.WriteLine($"Key size = {data.keySize}"); foreach (var kv in data.locations) { Console.WriteLine($"{kv.Key} = {kv.Value}"); } break; case "ls": Console.WriteLine( VirtualDirectoryListing.List(fs.GetExtendedEntities(currentDirectory))); break; case "ll": Console.WriteLine( VirtualDirectoryListing.ListWithHash(fs.GetExtendedEntities(currentDirectory))); break; case "put": if (data.locations.Count == 0) { Console.WriteLine("[Error]: No file locations setup"); break; } fileName = input.Split(" ")[1].Trim(); byte[] fileDataPut = System.IO.File.ReadAllBytes(fileName); //string encFile = AESWrapper.EncryptToString(fileData, key); Stopwatch watch1 = new Stopwatch(); watch1.Start(); using (Stream f = fs.CreateFile(FileSystemPath.Parse(currentDirectory.Path + fileName))) { f.Write(fileDataPut, 0, fileDataPut.Length); } fs.FlushTempFile(); dbfile.Flush(); watch1.Stop(); Console.WriteLine($"Elapsed time: {watch1.Elapsed.ToString("g")}"); break; case "localcat": if (data.locations.Count == 0) { Console.WriteLine("[Error]: No file locations setup"); break; } fileName = input.Split(" ")[1].Trim(); fileData = System.IO.File.ReadAllBytes(fileName); Console.WriteLine(AESWrapper.DecryptToString(fileData, key)); break; case "remotecat": if (data.locations.Count == 0) { Console.WriteLine("[Error]: No file locations setup"); break; } fileName = input.Split(" ")[1].Trim(); try { using (Stream f = fs.OpenFile( FileSystemPath.Parse(currentDirectory.Path + fileName), FileAccess.Read)) { Console.WriteLine(f.ReadAllText()); } } catch (Exception e) { Console.WriteLine("[Error]: " + e.ToString()); } break; case "get": if (data.locations.Count == 0) { Console.WriteLine("[Error]: No file locations setup"); break; } fileName = input.Split(" ")[1].Trim(); string dstFileName = input.Split(" ")[2].Trim(); Stopwatch watch2 = new Stopwatch(); watch2.Start(); using (Stream f = fs.OpenFile(FileSystemPath.Parse(currentDirectory.Path + fileName), FileAccess.Read)) { byte[] test = f.ReadAllBytes(); System.IO.File.WriteAllBytes(dstFileName, test); } watch2.Stop(); Console.WriteLine($"Elapsed time: {watch2.Elapsed.ToString("g")}"); break; case "mkdir": string newDir = input.Split(" ")[1].Trim(); fs.CreateDirectory(currentDirectory.AppendDirectory(newDir)); dbfile.Flush(); break; case "cd": string dirtmpStr; //dirtmp = currentDirectory.AppendDirectory(input.Split(" ")[1]); dirtmpStr = ParseDotDot(currentDirectory.Path, input.Split(" ")[1]); FileSystemPath dirtmp; if (dirtmpStr == "/") { dirtmp = FileSystemPath.Parse(dirtmpStr); } else { dirtmp = FileSystemPath.Parse(dirtmpStr + "/"); } if (fs.Exists(dirtmp)) { //currentDirectory = currentDirectory.AppendDirectory(input.Split(" ")[1]); currentDirectory = dirtmp; } else { Console.WriteLine("No such directory exists"); } break; } if (arguments.Length > 1) { break; } } while (input != "exit" && input != "quit"); dbfile.Flush(); } } }
/// <summary> /// Copies an entity from a source file system to a destination file system (async with cancellation token). /// </summary> public async Task CopyAsync(IFileSystem source, FileSystemPath sourcePath, IFileSystem destination, FileSystemPath destinationPath, CancellationToken cancellationToken) { var pSource = (PhysicalFileSystem)source; var pDestination = (PhysicalFileSystem)destination; var pSourcePath = pSource.GetPhysicalPath(sourcePath); var pDestinationPath = pDestination.GetPhysicalPath(destinationPath); if (sourcePath.IsFile) { await CopyFileAsyncInternal(pSourcePath, pDestinationPath, cancellationToken, BufferSize); } else { destination.CreateDirectory(destinationPath); foreach (var e in source.GetEntities(sourcePath)) { await source.CopyAsync(e, destination, e.IsFile?destinationPath.AppendFile(e.EntityName) : destinationPath.AppendDirectory(e.EntityName), cancellationToken); } } }
/// <summary> /// Copies an entity from a source file system to a destination file system. /// </summary> public void Copy(IFileSystem source, FileSystemPath sourcePath, IFileSystem destination, FileSystemPath destinationPath) { var pSource = (PhysicalFileSystem)source; var pDestination = (PhysicalFileSystem)destination; var pSourcePath = pSource.GetPhysicalPath(sourcePath); var pDestinationPath = pDestination.GetPhysicalPath(destinationPath); if (sourcePath.IsFile) { System.IO.File.Copy(pSourcePath, pDestinationPath); } else { destination.CreateDirectory(destinationPath); foreach (var e in source.GetEntities(sourcePath)) { source.Copy(e, destination, e.IsFile ? destinationPath.AppendFile(e.EntityName) : destinationPath.AppendDirectory(e.EntityName)); } } }