public override void Shutdown() { if (timeout_owner) { NoteOfTheDay.CleanupOld(manager); timeout.Timeout -= CheckNewDay; timeout.Cancel(); timeout = null; } initialized = false; }
public override SyncServer CreateSyncServer() { SyncServer server = null; // Cancel timer unmountTimeout.Cancel(); // Mount if necessary if (IsConfigured) { if (!IsMounted && !MountFuse(true)) // MountFuse may throw TomboySyncException! { throw new Exception("Could not mount " + mountPath); } server = new FileSystemSyncServer(mountPath); } else { throw new InvalidOperationException("CreateSyncServer called without being configured"); } // Return FileSystemSyncServer return(server); }
public void Delete() { save_timeout.Cancel(); }
public virtual bool CommitSyncTransaction() { bool commitSucceeded = false; if (updatedNotes.Count > 0 || deletedNotes.Count > 0) { // TODO: error-checking, etc string manifestFilePath = Path.Combine(newRevisionPath, "manifest.xml"); if (!Directory.Exists(newRevisionPath)) { DirectoryInfo info = Directory.CreateDirectory(newRevisionPath); AdjustPermissions(info.Parent.FullName); AdjustPermissions(newRevisionPath); } XmlNodeList noteNodes = null; if (IsValidXmlFile(manifestPath) == true) { using (FileStream fs = new FileStream(manifestPath, FileMode.Open)) { bool ok; Stream plainStream = SecurityWrapper.DecryptFromStream(manifestPath, fs, myKey, out ok); if (!ok) { throw new Exception("ENCRYPTION ERROR!"); } XmlDocument doc = new XmlDocument(); doc.Load(plainStream); noteNodes = doc.SelectNodes("//note"); } } else { using (StringReader sr = new StringReader("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<sync>\n</sync>")) { XmlDocument doc = new XmlDocument(); doc.Load(sr); noteNodes = doc.SelectNodes("//note"); } } #region createManifestFile // Write out the new manifest file MemoryStream plainBuf = new MemoryStream(); XmlWriter xml = XmlWriter.Create(plainBuf, XmlEncoder.DocumentSettings); try { xml.WriteStartDocument(); xml.WriteStartElement(null, "sync", null); xml.WriteAttributeString("revision", newRevision.ToString()); xml.WriteAttributeString("server-id", serverId); foreach (XmlNode node in noteNodes) { string id = node.SelectSingleNode("@id").InnerText; string rev = node.SelectSingleNode("@rev").InnerText; // Don't write out deleted notes if (deletedNotes.Contains(id)) { continue; } // Skip updated notes, we'll update them in a sec if (updatedNotes.Contains(id)) { continue; } xml.WriteStartElement(null, "note", null); xml.WriteAttributeString("id", id); xml.WriteAttributeString("rev", rev); xml.WriteEndElement(); } // Write out all the updated notes foreach (string uuid in updatedNotes) { xml.WriteStartElement(null, "note", null); xml.WriteAttributeString("id", uuid); xml.WriteAttributeString("rev", newRevision.ToString()); xml.WriteEndElement(); } xml.WriteEndElement(); xml.WriteEndDocument(); } finally { xml.Close(); // now store in encrypted version: SecurityWrapper.SaveAsEncryptedFile(manifestFilePath, plainBuf.ToArray(), myKey); // dispose of plain data plainBuf.Dispose(); } AdjustPermissions(manifestFilePath); #endregion // only use this if we use the revision-folder-mode if (!manifestFilePath.Equals(manifestPath)) { #region DIR_VERSION // Rename original /manifest.xml to /manifest.xml.old string oldManifestPath = manifestPath + ".old"; if (File.Exists(manifestPath) == true) { if (File.Exists(oldManifestPath)) { File.Delete(oldManifestPath); } File.Move(manifestPath, oldManifestPath); } // * * * Begin Cleanup Code * * * // TODO: Consider completely discarding cleanup code, in favor // of periodic thorough server consistency checks (say every 30 revs). // Even if we do continue providing some cleanup, consistency // checks should be implemented. // Copy the /${parent}/${rev}/manifest.xml -> /manifest.xml // don't encrypt here because file is already encrypted! //SecurityWrapper.CopyAndEncrypt(manifestFilePath, manifestPath, myKey); File.Copy(manifestFilePath, manifestPath, true); AdjustPermissions(manifestPath); try { // Delete /manifest.xml.old if (File.Exists(oldManifestPath)) { File.Delete(oldManifestPath); } string oldManifestFilePath = Path.Combine(GetRevisionDirPath(newRevision - 1), "manifest.xml"); if (File.Exists(oldManifestFilePath)) { // TODO: Do step #8 as described in http://bugzilla.gnome.org/show_bug.cgi?id=321037#c17 // Like this? FileInfo oldManifestFilePathInfo = new FileInfo(oldManifestFilePath); foreach (FileInfo file in oldManifestFilePathInfo.Directory.GetFiles()) { string fileGuid = Path.GetFileNameWithoutExtension(file.Name); if (deletedNotes.Contains(fileGuid) || updatedNotes.Contains(fileGuid)) { File.Delete(file.FullName); } // TODO: Need to check *all* revision dirs, not just previous (duh) // Should be a way to cache this from checking earlier. } // TODO: Leaving old empty dir for now. Some stuff is probably easier // when you can guarantee the existence of each intermediate directory? } } catch (Exception e) { Logger.Error("Exception during server cleanup while committing. " + "Server integrity is OK, but there may be some excess " + "files floating around. Here's the error:\n"+ e.Message); } #endregion } else { Logger.Info("probably doing sync without revision-hierarchy"); OnManifestFileCreated(manifestFilePath); // this is just a simple cleanup because we only use one directory // delete the notes that were deleted in this one directory: try { FileInfo manifestFilePathInfo = new FileInfo(manifestFilePath); foreach (FileInfo file in manifestFilePathInfo.Directory.GetFiles()) { string fileGuid = Path.GetFileNameWithoutExtension(file.Name); if (deletedNotes.Contains(fileGuid)) { File.Delete(file.FullName); OnDeleteFile(file.FullName); } if (updatedNotes.Contains(fileGuid)) { OnUploadFile(file.FullName); } } } catch (Exception e) { Logger.Error("Exception during server cleanup while committing. " + "Server integrity is OK, but there may be some excess " + "files floating around. Here's the error:\n"+ e.Message); } } } else { // no changes (no updates/deletes) } lockTimeout.Cancel(); RemoveLockFile(lockPath); commitSucceeded = true; // TODO: When return false? return(commitSucceeded); }
public virtual bool CommitSyncTransaction() { bool commitSucceeded = false; if (updatedNotes.Count > 0 || deletedNotes.Count > 0) { // TODO: error-checking, etc string manifestFilePath = Path.Combine(newRevisionPath, "manifest.xml"); if (!Directory.Exists(newRevisionPath)) { DirectoryInfo info = Directory.CreateDirectory(newRevisionPath); AdjustPermissions(info.Parent.FullName); AdjustPermissions(newRevisionPath); } XmlNodeList noteNodes = null; if (IsValidXmlFile(manifestPath) == true) { using (FileStream fs = new FileStream(manifestPath, FileMode.Open)) { XmlDocument doc = new XmlDocument(); doc.Load(fs); noteNodes = doc.SelectNodes("//note"); } } else { using (StringReader sr = new StringReader("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<sync>\n</sync>")) { XmlDocument doc = new XmlDocument(); doc.Load(sr); noteNodes = doc.SelectNodes("//note"); } } // Write out the new manifest file XmlWriter xml = XmlWriter.Create(manifestFilePath, XmlEncoder.DocumentSettings); try { xml.WriteStartDocument(); xml.WriteStartElement(null, "sync", null); xml.WriteAttributeString("revision", newRevision.ToString()); xml.WriteAttributeString("server-id", serverId); foreach (XmlNode node in noteNodes) { string id = node.SelectSingleNode("@id").InnerText; string rev = node.SelectSingleNode("@rev").InnerText; // Don't write out deleted notes if (deletedNotes.Contains(id)) { continue; } // Skip updated notes, we'll update them in a sec if (updatedNotes.Contains(id)) { continue; } xml.WriteStartElement(null, "note", null); xml.WriteAttributeString("id", id); xml.WriteAttributeString("rev", rev); xml.WriteEndElement(); } // Write out all the updated notes foreach (string uuid in updatedNotes) { xml.WriteStartElement(null, "note", null); xml.WriteAttributeString("id", uuid); xml.WriteAttributeString("rev", newRevision.ToString()); xml.WriteEndElement(); } xml.WriteEndElement(); xml.WriteEndDocument(); } finally { xml.Close(); } AdjustPermissions(manifestFilePath); // Rename original /manifest.xml to /manifest.xml.old string oldManifestPath = manifestPath + ".old"; if (File.Exists(manifestPath) == true) { if (File.Exists(oldManifestPath)) { File.Delete(oldManifestPath); } File.Move(manifestPath, oldManifestPath); } // * * * Begin Cleanup Code * * * // TODO: Consider completely discarding cleanup code, in favor // of periodic thorough server consistency checks (say every 30 revs). // Even if we do continue providing some cleanup, consistency // checks should be implemented. // Copy the /${parent}/${rev}/manifest.xml -> /manifest.xml File.Copy(manifestFilePath, manifestPath); AdjustPermissions(manifestPath); try { // Delete /manifest.xml.old if (File.Exists(oldManifestPath)) { File.Delete(oldManifestPath); } string oldManifestFilePath = Path.Combine(GetRevisionDirPath(newRevision - 1), "manifest.xml"); if (File.Exists(oldManifestFilePath)) { // TODO: Do step #8 as described in http://bugzilla.gnome.org/show_bug.cgi?id=321037#c17 // Like this? FileInfo oldManifestFilePathInfo = new FileInfo(oldManifestFilePath); foreach (FileInfo file in oldManifestFilePathInfo.Directory.GetFiles()) { string fileGuid = Path.GetFileNameWithoutExtension(file.Name); if (deletedNotes.Contains(fileGuid) || updatedNotes.Contains(fileGuid)) { File.Delete(file.FullName); } // TODO: Need to check *all* revision dirs, not just previous (duh) // Should be a way to cache this from checking earlier. } // TODO: Leaving old empty dir for now. Some stuff is probably easier // when you can guarantee the existence of each intermediate directory? } } catch (Exception e) { Logger.Error("Exception during server cleanup while committing. " + "Server integrity is OK, but there may be some excess " + "files floating around. Here's the error:\n" + e.Message); } // * * * End Cleanup Code * * * } lockTimeout.Cancel(); File.Delete(lockPath); // TODO: Errors? commitSucceeded = true; // TODO: When return false? return(commitSucceeded); }