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); } } } }
public OpStorage GetStorage(ulong key) { OpStorage storage = null; StorageMap.SafeTryGetValue(key, out storage); return(storage); }
void Cache_FileRemoved(OpVersionedFile file) { OpStorage storage = GetStorage(file.UserID); if (storage != null) { UnloadHeaderFile(GetFilePath(storage), storage.File.Header.FileKey); } StorageMap.SafeRemove(file.UserID); }
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; }
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); } }
public string GetFilePath(OpStorage storage) { return(Cache.GetFilePath(storage.File.Header)); }
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); } }
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)); } }
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(); } }
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); }
public string GetFilePath(OpStorage storage) { return Cache.GetFilePath(storage.File.Header); }
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); } }