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; }
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); } }