public override void Shutdown()
        {
            if (timeout_owner)
            {
                NoteOfTheDay.CleanupOld(manager);
                timeout.Timeout -= CheckNewDay;
                timeout.Cancel();
                timeout = null;
            }

            initialized = false;
        }
예제 #2
0
        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);
        }
예제 #3
0
 public void Delete()
 {
     save_timeout.Cancel();
 }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }