Esempio n. 1
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();
                }
            }
        }
 public override void Dispose()
 {
     base.Dispose();
     dbfile.Flush();
     dbfile.Dispose();
 }