Example #1
0
        void Trust_Update(OpTrust trust)
        {
            // update working projects (add)
            if (trust.UserID == Core.UserID)
            {
                OpStorage local = GetStorage(Core.UserID);

                foreach (uint project in Trust.LocalTrust.Links.Keys)
                {
                    if (!Working.ContainsKey(project))
                    {
                        if (local != null)
                        {
                            LoadHeaderFile(GetWorkingPath(project), local, false, true);
                        }

                        Working[project] = new WorkingStorage(this, project);
                    }
                }
            }

            // remove all higher changes, reload with new highers (cause link changed
            foreach (WorkingStorage working in Working.Values)
            {
                if (Core.UserID == trust.UserID || Trust.IsHigher(trust.UserID, working.ProjectID))
                {
                    working.RemoveAllHigherChanges();

                    foreach (ulong uplink in Trust.GetAutoInheritIDs(Core.UserID, working.ProjectID))
                    {
                        working.RefreshHigherChanges(uplink);
                    }
                }
            }
        }
Example #2
0
        public OpStorage GetStorage(ulong key)
        {
            OpStorage storage = null;

            StorageMap.SafeTryGetValue(key, out storage);

            return(storage);
        }
Example #3
0
        void Cache_FileRemoved(OpVersionedFile file)
        {
            OpStorage storage = GetStorage(file.UserID);

            if (storage != null)
            {
                UnloadHeaderFile(GetFilePath(storage), storage.File.Header.FileKey);
            }

            StorageMap.SafeRemove(file.UserID);
        }
Example #4
0
        public StorageService(OpCore core)
        {
            Core     = core;
            Network  = core.Network;
            Protocol = Network.Protocol;
            Store    = Network.Store;
            Trust    = Core.Trust;

            Core.SecondTimerEvent += Core_SecondTimer;
            Core.MinuteTimerEvent += Core_MinuteTimer;

            Network.CoreStatusChange += new StatusChange(Network_StatusChange);

            Core.Transfers.FileSearch[ServiceID, FileTypeData]  += new FileSearchHandler(Transfers_DataFileSearch);
            Core.Transfers.FileRequest[ServiceID, FileTypeData] += new FileRequestHandler(Transfers_DataFileRequest);

            Core.Trust.LinkUpdate += new LinkUpdateHandler(Trust_Update);

            LocalFileKey  = Core.User.Settings.FileKey;
            FileCrypt.Key = LocalFileKey;
            FileCrypt.IV  = new byte[FileCrypt.IV.Length];

            string rootpath = Core.User.RootPath + Path.DirectorySeparatorChar + "Data" + Path.DirectorySeparatorChar + ServiceID.ToString() + Path.DirectorySeparatorChar;

            DataPath     = rootpath + FileTypeData.ToString();
            WorkingPath  = rootpath + FileTypeWorking.ToString();
            ResourcePath = rootpath + FileTypeResource.ToString();

            Directory.CreateDirectory(DataPath);
            Directory.CreateDirectory(WorkingPath);

            // clear resource files so that updates of these files work
            if (Directory.Exists(ResourcePath))
            {
                Directory.Delete(ResourcePath, true);
            }

            Cache = new VersionedCache(Network, ServiceID, FileTypeCache, false);

            Cache.FileAquired += new FileAquiredHandler(Cache_FileAquired);
            Cache.FileRemoved += new FileRemovedHandler(Cache_FileRemoved);
            Cache.Load();


            // load working headers
            OpStorage local = GetStorage(Core.UserID);

            foreach (uint project in Trust.LocalTrust.Links.Keys)
            {
                if (local != null)
                {
                    LoadHeaderFile(GetWorkingPath(project), local, false, true);
                }

                Working[project] = new WorkingStorage(this, project);

                bool doSave = false;
                foreach (ulong higher in Trust.GetAutoInheritIDs(Core.UserID, project))
                {
                    if (Working[project].RefreshHigherChanges(higher))
                    {
                        doSave = true;
                    }
                }

                Working[project].AutoIntegrate(doSave);
            }

            foreach (string testPath in Directory.GetFiles(DataPath))
            {
                if (!ReferencedPaths.Contains(testPath))
                {
                    try { File.Delete(testPath); }
                    catch { }
                }
            }

            ReferencedPaths.Clear();
            Loading = false;
        }
Example #5
0
        private void LoadHeaderFile(string path, OpStorage storage, bool reload, bool working)
        {
            try
            {
                if (!File.Exists(path))
                {
                    return;
                }

                bool cached = Network.Routing.InCacheArea(storage.UserID);
                bool local  = false;

                byte[] key = working ? LocalFileKey : storage.File.Header.FileKey;

                using (TaggedStream filex = new TaggedStream(path, Network.Protocol))
                    using (IVCryptoStream crypto = IVCryptoStream.Load(filex, key))
                    {
                        PacketStream stream = new PacketStream(crypto, Protocol, FileAccess.Read);

                        G2Header header = null;

                        ulong currentUID = 0;

                        while (stream.ReadPacket(ref header))
                        {
                            if (!working && header.Name == StoragePacket.Root)
                            {
                                StorageRoot packet = StorageRoot.Decode(header);

                                local = Core.UserID == storage.UserID ||
                                        GetHigherRegion(Core.UserID, packet.ProjectID).Contains(storage.UserID) ||
                                        Trust.GetDownlinkIDs(Core.UserID, packet.ProjectID, 1).Contains(storage.UserID);
                            }

                            if (header.Name == StoragePacket.File)
                            {
                                StorageFile packet = StorageFile.Decode(header);

                                if (packet == null)
                                {
                                    continue;
                                }

                                bool historyFile = true;
                                if (packet.UID != currentUID)
                                {
                                    historyFile = false;
                                    currentUID  = packet.UID;
                                }

                                OpFile file = null;
                                if (!FileMap.SafeTryGetValue(packet.HashID, out file))
                                {
                                    file = new OpFile(packet);
                                    FileMap.SafeAdd(packet.HashID, file);
                                }

                                InternalFileMap.SafeAdd(packet.InternalHashID, file);

                                if (!reload)
                                {
                                    file.References++;
                                }

                                if (!working) // if one ref is public, then whole file is marked public
                                {
                                    file.Working = false;
                                }

                                if (packet.HashID == 0 || packet.InternalHash == null)
                                {
                                    Debug.Assert(false);
                                    continue;
                                }

                                string filepath = GetFilePath(packet.HashID);
                                file.Downloaded = File.Exists(filepath);

                                if (Loading && file.Downloaded && !ReferencedPaths.Contains(filepath))
                                {
                                    ReferencedPaths.Add(filepath);
                                }

                                if (!file.Downloaded)
                                {
                                    // if in local range only store latest
                                    if (local && !historyFile)
                                    {
                                        DownloadFile(storage.UserID, packet);
                                    }

                                    // if storage is in cache range, download all files
                                    else if (Network.Established && cached)
                                    {
                                        DownloadFile(storage.UserID, packet);
                                    }
                                }

                                // on link update, if in local range, get latest files
                                // (handled by location update, when it sees a new version of storage component is available)
                            }
                        }
                    }
            }
            catch (Exception ex)
            {
                Core.Network.UpdateLog("Storage", "Error loading files " + ex.Message);
            }
        }
Example #6
0
 public string GetFilePath(OpStorage storage)
 {
     return(Cache.GetFilePath(storage.File.Header));
 }
Example #7
0
        void Cache_FileAquired(OpVersionedFile file)
        {
            // unload old file
            OpStorage prevStorage = GetStorage(file.UserID);

            if (prevStorage != null)
            {
                string oldPath = GetFilePath(prevStorage);

                UnloadHeaderFile(oldPath, prevStorage.File.Header.FileKey);
            }

            OpStorage newStorage = new OpStorage(file);

            StorageMap.SafeAdd(file.UserID, newStorage);


            LoadHeaderFile(GetFilePath(newStorage), newStorage, false, false);

            // record changes of higher nodes for auto-integration purposes
            Trust.ProjectRoots.LockReading(delegate()
            {
                foreach (uint project in Trust.ProjectRoots.Keys)
                {
                    List <ulong> inheritIDs = Trust.GetAutoInheritIDs(Core.UserID, project);

                    if (Core.UserID == newStorage.UserID || inheritIDs.Contains(newStorage.UserID))
                    {
                        // doesnt get called on startup because working not initialized before headers are loaded
                        if (Working.ContainsKey(project))
                        {
                            bool doSave = Working[project].RefreshHigherChanges(newStorage.UserID);

                            if (!Loading && !SavingLocal)
                            {
                                Working[project].AutoIntegrate(doSave);
                            }
                        }
                    }
                }
            });

            // update subs - this ensures file not propagated lower until we have it (prevents flood to original poster)
            if (Network.Established)
            {
                List <LocationData> locations = new List <LocationData>();

                Trust.ProjectRoots.LockReading(delegate()
                {
                    foreach (uint project in Trust.ProjectRoots.Keys)
                    {
                        if (newStorage.UserID == Core.UserID || Trust.IsHigher(newStorage.UserID, project))
                        {
                            Trust.GetLocsBelow(Core.UserID, project, locations);
                        }
                    }
                });

                Store.PublishDirect(locations, newStorage.UserID, ServiceID, FileTypeCache, file.SignedHeader);
            }

            if (StorageUpdate != null)
            {
                Core.RunInGuiThread(StorageUpdate, newStorage);
            }

            if (Core.NewsWorthy(newStorage.UserID, 0, false))
            {
                Core.MakeNews(ServiceIDs.Storage, "File System updated by " + Core.GetName(newStorage.UserID), newStorage.UserID, 0, false);
            }
        }
Example #8
0
        public void SaveLocal(uint project)
        {
            try
            {
                string tempPath = Core.GetTempPath();
                byte[] key      = Utilities.GenerateKey(Core.StrongRndGen, 256);

                using (IVCryptoStream stream = IVCryptoStream.Save(tempPath, key))
                {
                    // write loaded projects
                    WorkingStorage working = null;
                    if (Working.ContainsKey(project))
                    {
                        working = Working[project];
                    }

                    if (working != null)
                    {
                        Protocol.WriteToFile(new StorageRoot(working.ProjectID), stream);
                        working.WriteWorkingFile(stream, working.RootFolder, true);

                        working.Modified = false;

                        try { File.Delete(GetWorkingPath(project)); }
                        catch { }
                    }

                    // open old file and copy entries, except for working
                    OpStorage local = GetStorage(Core.UserID);

                    if (local != null)
                    {
                        string oldPath = GetFilePath(local);

                        if (File.Exists(oldPath))
                        {
                            using (TaggedStream file = new TaggedStream(oldPath, Network.Protocol))
                                using (IVCryptoStream crypto = IVCryptoStream.Load(file, local.File.Header.FileKey))
                                {
                                    PacketStream oldStream = new PacketStream(crypto, Protocol, FileAccess.Read);
                                    bool         write     = false;
                                    G2Header     g2header  = null;

                                    while (oldStream.ReadPacket(ref g2header))
                                    {
                                        if (g2header.Name == StoragePacket.Root)
                                        {
                                            StorageRoot root = StorageRoot.Decode(g2header);

                                            write = (root.ProjectID != project);
                                        }

                                        //copy packet right to new file
                                        if (write) //crit test
                                        {
                                            stream.Write(g2header.Data, g2header.PacketPos, g2header.PacketSize);
                                        }
                                    }
                                }
                        }
                    }

                    stream.WriteByte(0); // signal last packet

                    stream.FlushFinalBlock();
                }

                SavingLocal = true; // prevents auto-integrate from re-calling saveLocal
                OpVersionedFile vfile = Cache.UpdateLocal(tempPath, key, BitConverter.GetBytes(Core.TimeNow.ToUniversalTime().ToBinary()));
                SavingLocal = false;

                Store.PublishDirect(Core.Trust.GetLocsAbove(), Core.UserID, ServiceID, FileTypeCache, vfile.SignedHeader);
            }
            catch (Exception ex)
            {
                Core.Network.UpdateLog("Storage", "Error updating local " + ex.Message);
            }

            if (StorageUpdate != null)
            {
                Core.RunInGuiThread(StorageUpdate, GetStorage(Core.UserID));
            }
        }
Example #9
0
        private void Storages_StorageUpdate(OpStorage storage)
        {
            if (storage.UserID == UserID)
                RefreshView();

            // re-apply diff
            if (CurrentDiffs.Contains(storage.UserID))
            {
                RemoveDiff(storage.UserID, RootFolder);
                ApplyDiff(storage.UserID);

                bool high = false, low = false;
                AnalyzeChanges(RootFolder, false, ref high, ref low);

                SelectedInfo.UpdateDiffView(storage.UserID);

                RefreshFileList();
            }
        }
Example #10
0
        void Cache_FileAquired(OpVersionedFile file)
        {
            // unload old file
            OpStorage prevStorage = GetStorage(file.UserID);
            if (prevStorage != null)
            {
                string oldPath = GetFilePath(prevStorage);

                UnloadHeaderFile(oldPath, prevStorage.File.Header.FileKey);
            }

            OpStorage newStorage = new OpStorage(file);

            StorageMap.SafeAdd(file.UserID, newStorage);

            LoadHeaderFile(GetFilePath(newStorage), newStorage, false, false);

            // record changes of higher nodes for auto-integration purposes
            Trust.ProjectRoots.LockReading(delegate()
            {
                foreach (uint project in Trust.ProjectRoots.Keys)
                {
                    List<ulong> inheritIDs = Trust.GetAutoInheritIDs(Core.UserID, project);

                    if (Core.UserID == newStorage.UserID || inheritIDs.Contains(newStorage.UserID))
                        // doesnt get called on startup because working not initialized before headers are loaded
                        if (Working.ContainsKey(project))
                        {
                            bool doSave = Working[project].RefreshHigherChanges(newStorage.UserID);

                            if (!Loading && !SavingLocal)
                                Working[project].AutoIntegrate(doSave);
                        }
                }
            });

            // update subs - this ensures file not propagated lower until we have it (prevents flood to original poster)
            if (Network.Established)
            {
                List<LocationData> locations = new List<LocationData>();

                Trust.ProjectRoots.LockReading(delegate()
                {
                    foreach (uint project in Trust.ProjectRoots.Keys)
                        if (newStorage.UserID == Core.UserID || Trust.IsHigher(newStorage.UserID, project))
                            Trust.GetLocsBelow(Core.UserID, project, locations);
                });

                Store.PublishDirect(locations, newStorage.UserID, ServiceID, FileTypeCache, file.SignedHeader);
            }

            if (StorageUpdate != null)
                Core.RunInGuiThread(StorageUpdate, newStorage);

            if (Core.NewsWorthy(newStorage.UserID, 0, false))
                Core.MakeNews(ServiceIDs.Storage, "File System updated by " + Core.GetName(newStorage.UserID), newStorage.UserID, 0, false);
        }
Example #11
0
 public string GetFilePath(OpStorage storage)
 {
     return Cache.GetFilePath(storage.File.Header);
 }
Example #12
0
        private void LoadHeaderFile(string path, OpStorage storage, bool reload, bool working)
        {
            try
            {
                if (!File.Exists(path))
                    return;

                bool cached = Network.Routing.InCacheArea(storage.UserID);
                bool local = false;

                byte[] key = working ? LocalFileKey : storage.File.Header.FileKey;

                using (TaggedStream filex = new TaggedStream(path, Network.Protocol))
                using (IVCryptoStream crypto = IVCryptoStream.Load(filex, key))
                {
                    PacketStream stream = new PacketStream(crypto, Protocol, FileAccess.Read);

                    G2Header header = null;

                    ulong currentUID = 0;

                    while (stream.ReadPacket(ref header))
                    {
                        if (!working && header.Name == StoragePacket.Root)
                        {
                            StorageRoot packet = StorageRoot.Decode(header);

                            local = Core.UserID == storage.UserID ||
                                    GetHigherRegion(Core.UserID, packet.ProjectID).Contains(storage.UserID) ||
                                    Trust.GetDownlinkIDs(Core.UserID, packet.ProjectID, 1).Contains(storage.UserID);
                        }

                        if (header.Name == StoragePacket.File)
                        {
                            StorageFile packet = StorageFile.Decode(header);

                            if (packet == null)
                                continue;

                            bool historyFile = true;
                            if (packet.UID != currentUID)
                            {
                                historyFile = false;
                                currentUID = packet.UID;
                            }

                            OpFile file = null;
                            if (!FileMap.SafeTryGetValue(packet.HashID, out file))
                            {
                                file = new OpFile(packet);
                                FileMap.SafeAdd(packet.HashID, file);
                            }

                            InternalFileMap.SafeAdd(packet.InternalHashID, file);

                            if (!reload)
                                file.References++;

                            if (!working) // if one ref is public, then whole file is marked public
                                file.Working = false;

                            if (packet.HashID == 0 || packet.InternalHash == null)
                            {
                                Debug.Assert(false);
                                continue;
                            }

                            string filepath = GetFilePath(packet.HashID);
                            file.Downloaded = File.Exists(filepath);

                            if (Loading && file.Downloaded && !ReferencedPaths.Contains(filepath))
                                ReferencedPaths.Add(filepath);

                            if (!file.Downloaded)
                            {
                                // if in local range only store latest
                                if (local && !historyFile)
                                    DownloadFile(storage.UserID, packet);

                                // if storage is in cache range, download all files
                                else if (Network.Established && cached)
                                    DownloadFile(storage.UserID, packet);
                            }

                            // on link update, if in local range, get latest files
                            // (handled by location update, when it sees a new version of storage component is available)
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Core.Network.UpdateLog("Storage", "Error loading files " + ex.Message);
            }
        }