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());
 }
예제 #3
0
 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"));
 }
예제 #4
0
 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();
 }
예제 #5
0
 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));
     }
 }
예제 #6
0
 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"));
 }
예제 #7
0
 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
 }
예제 #8
0
        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();
                }
            }
        }
예제 #9
0
        /// <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);
                }
            }
        }
예제 #10
0
        /// <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));
                }
            }
        }