Exemple #1
0
        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            //ServicePointManager.ServerCertificateValidationCallback=delegate
            //{
            //    return true;
            //};

            RemoteCertificateValidationCallback certificateCallback=new RemoteCertificateValidationCallback(ValidateServerCertificate);

            string syncFolder=Globals.Options.GetElementAsString("xml.Options.Paths.SyncFolder");

            string ftpServer=Globals.Options.GetElementAsString("xml.Options.FTP.Server");
            string ftpUser=Globals.Options.GetElementAsString("xml.Options.FTP.User");
            string ftpPassword=Globals.Options.GetElementAsString("xml.Options.FTP.Password");
            string ftpProtocol=Globals.Options.GetElementAsString("xml.Options.FTP.Protocol");

            if(FileSystem.ExistsDirectory(syncFolder))
            {
                if(ftpServer!=""&&ftpUser!=""&ftpPassword!=""&ftpProtocol!="")
                {
                    //Connect
                    FTPSClient client=new FTPSClient();

                    //NetworkCredital
                    NetworkCredential credential=new NetworkCredential(ftpUser, ftpPassword);

                    //client.Connect(ftpServer, credential, ESSLSupportMode.ControlAndDataChannelsRequired);

                    client.Connect(ftpServer, credential, ESSLSupportMode.ControlAndDataChannelsRequired, certificateCallback);

                    #region Verzeichnisstruktur überprüfen und nach Bedarf anlegen
                    //Test auf leeres Verzeichnis
                    IList<DirectoryListItem> files=client.GetDirectoryList();

                    bool existXData=false;
                    bool existHData=false;
                    bool existLData=false;

                    bool existCData=false;
                    bool existMData=false;
                    bool existRData=false;

                    bool existCfsInfo=false;

                    foreach(DirectoryListItem file in files)
                    {
                        if(file.IsDirectory)
                        {
                            switch(file.Name)
                            {
                                case "x-data":
                                    {
                                        existXData=true;
                                        break;
                                    }
                                case "h-data":
                                    {
                                        existHData=true;
                                        break;
                                    }
                                case "l-data":
                                    {
                                        existLData=true;
                                        break;
                                    }
                                case "c-data":
                                    {
                                        existCData=true;
                                        break;
                                    }
                                case "m-data":
                                    {
                                        existMData=true;
                                        break;
                                    }
                                case "r-data":
                                    {
                                        existRData=true;
                                        break;
                                    }

                            }
                        }
                        else //File
                        {
                            switch(file.Name)
                            {
                                case "cfsinfo":
                                    {
                                        existCfsInfo=true;
                                        break;
                                    }
                            }
                        }
                    }

                    //CfsInfo anlegen
                    if(existCfsInfo==false)
                    {
                        List<string> version=new List<string>();
                        version.Add("1"); //Repository Version

                        string versionFilenameLocal=FileSystem.TempPath+"cfsinfo-"+Various.GetTimeID();
                        File.WriteAllLines(versionFilenameLocal, version.ToArray());
                        client.PutFile(versionFilenameLocal, "cfsinfo");
                    }
                    else //Version überprüfen
                    {
                        string versionFilenameLocal=FileSystem.TempPath+"cfsinfo-"+Various.GetTimeID();
                        client.GetFile("cfsinfo", versionFilenameLocal);

                        string[] cfsinfo=File.ReadAllLines(versionFilenameLocal);
                        int version=Convert.ToInt32(cfsinfo[0]);

                        if(version!=1)
                        {
                            MessageBox.Show("CloudFileSync ist nicht mit der Version des Repositories kompatibel!", "Hinweis", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return;
                        }
                    }

                    if(existXData==false) client.MakeDir("x-data"); //Datenordner
                    if(existHData==false) client.MakeDir("h-data"); //Hashdaten
                    if(existLData==false) client.MakeDir("l-data"); //Lockdaten

                    if(existCData==false) client.MakeDir("c-data"); //Createdaten
                    if(existMData==false) client.MakeDir("m-data"); //Modifieddaten
                    if(existRData==false) client.MakeDir("r-data"); //Removedaten

                    //Überprüfen ob meine Clientverzeichnisse existieren
                    CheckAndCreateClientFolder(client, "c-data");
                    CheckAndCreateClientFolder(client, "m-data");
                    CheckAndCreateClientFolder(client, "r-data");
                    #endregion

                    //Init Datenbestand (Sync)
                    UpdateFromRemote(client, syncFolder);

                    //Neu erzeugte oder geänderte Dateien ermitteln
                    List<string> syncFolderFiles=FileSystem.GetFiles(syncFolder, true); //Neue Lokale Dateien hochladen

                    foreach(string file in syncFolderFiles)
                    {
                        string relFilename=FileSystem.GetRelativePath(file, syncFolder, true);
                        string hashRemote=GetHistoryHash(client, relFilename);
                        string hashLocal=Hash.SHA1.HashFile(file);

                        if(hashRemote!=hashLocal)
                        {
                            filesCreated.Add(file);
                        }
                    }

                    //gelöschte Dateien ermitteln
                    List<string> hashFiles=GetHashFiles(client);

                    foreach(string hashFile in hashFiles)
                    {
                        string filenameToTest=FileSystem.GetPathWithPathDelimiter(syncFolder)+hashFile.Replace('\\', FileSystem.PathDelimiter);
                        syncFolderFiles.Remove(filenameToTest);
                    }

                    foreach(string file in syncFolderFiles)
                    {
                        if(filesCreated.IndexOf(file)==-1) //Datei soll nicht hochgeladen werden, sondern wurde wirklich auf einem anderen Client gelöscht
                        {
                            string relFilename=FileSystem.GetRelativePath(file, syncFolder, true);
                            FileSystem.RemoveFile(file);
                            Globals.Log.Add(LogLevel.Information, "Lokal: Datei {0} wurde gelöscht.", relFilename);
                        }
                    }

                    //FilesystemWatcher aktivieren
                    fileSystemWatcher.Path=syncFolder;
                    fileSystemWatcher.EnableRaisingEvents=true;

                    #region Endlosschleife für Syncronisation
                    while(true)
                    {
                        if(e.Cancel==true) return;

                        List<string> fileToRemoveFromList=new List<string>();

                        //Dateien hochladen
                        #region Created files
                        lock(filesCreated)
                        {
                            foreach(string fileCreated in filesCreated)
                            {
                                string relFilename=FileSystem.GetRelativePath(fileCreated, syncFolder, true);
                                relFilename=relFilename.Replace("\\", "/");

                                bool locked=GetFileLock(client, relFilename);

                                if(locked)
                                {
                                    if(FileSystem.IsDirectory(fileCreated)) //Directory
                                    {
                                        client.CreateDirectory("x-data/"+relFilename);
                                        fileToRemoveFromList.Add(fileCreated);
                                        Globals.Log.Add(LogLevel.Information, "Remote: Verzeichnis {0} wurde erstellt (x-data).", relFilename);

                                        //In Created Verzeichnisse legen
                                        AddFileToUpdateFolder(client, "c-data", relFilename, EFileType.Directory);
                                        //Globals.Log.Add(LogLevel.Information, "Updatedatei {0} wurde hochgeladen (c-data).", relFilename);
                                    }
                                    else //File
                                    {
                                        //Hashdatei ändern
                                        AddHistoryHash(client, fileCreated, relFilename);
                                        Globals.Log.Add(LogLevel.Information, "Remote: Hash für {0} wurde geändert (x-data).", relFilename);

                                        //Datei hochladen
                                        CreateFTPDirectories(client, "x-data/"+relFilename);
                                        client.PutFile(fileCreated, "x-data/"+relFilename);
                                        fileToRemoveFromList.Add(fileCreated);
                                        Globals.Log.Add(LogLevel.Information, "Remote: Datei {0} wurde hochgeladen (x-data).", relFilename);

                                        //In Created Verzeichnisse legen
                                        AddFileToUpdateFolder(client, "c-data", relFilename, EFileType.File);
                                        //Globals.Log.Add(LogLevel.Information, "Updatedatei {0} wurde hochgeladen (c-data).", relFilename);
                                    }
                                }

                                RemoveFileLock(client, relFilename);
                            }

                            foreach(string rFile in fileToRemoveFromList)
                            {
                                filesCreated.Remove(rFile);
                            }
                        }

                        fileToRemoveFromList.Clear();
                        #endregion

                        #region Changed Files
                        lock(filesChanged)
                        {
                            foreach(string fileChanged in filesChanged)
                            {
                                string relFilename=FileSystem.GetRelativePath(fileChanged, syncFolder, true);
                                relFilename=relFilename.Replace("\\", "/");

                                bool locked=GetFileLock(client, relFilename);

                                if(locked)
                                {
                                    if(FileSystem.IsDirectory(fileChanged)) //Directory
                                    {
                                        //Sollte bei Verzeichnissen ignoriert werden
                                    }
                                    else //File
                                    {
                                        //Hashdatei ändern
                                        AddHistoryHash(client, fileChanged, relFilename);
                                        Globals.Log.Add(LogLevel.Information, "Remote: Hash für {0} wurde geändert (x-data).", relFilename);

                                        //Datei hochladen
                                        client.PutFile(fileChanged, "x-data/"+relFilename);
                                        fileToRemoveFromList.Add(fileChanged);
                                        Globals.Log.Add(LogLevel.Information, "Remote: Datei {0} wurde modifiziert (x-data).", relFilename);

                                        //In Created Verzeichnisse legen
                                        AddFileToUpdateFolder(client, "m-data", relFilename, EFileType.File);
                                    }
                                }

                                RemoveFileLock(client, relFilename);
                            }

                            foreach(string rFile in fileToRemoveFromList)
                            {
                                filesChanged.Remove(rFile);
                            }
                        }

                        fileToRemoveFromList.Clear();
                        #endregion

                        #region Deleted Files
                        lock(filesDeleted)
                        {
                            foreach(string fileDeleted in filesDeleted)
                            {
                                string relFilename=FileSystem.GetRelativePath(fileDeleted, syncFolder, true);
                                relFilename=relFilename.Replace("\\", "/");

                                bool locked=GetFileLock(client, relFilename);

                                if(locked)
                                {
                                    if(FileSystem.IsDirectory(fileDeleted)) //Directory
                                    {
                                        client.RemoveDir(fileDeleted);
                                        //client.PutFile(fileChanged, "x-data/"+relFilename);
                                        fileToRemoveFromList.Add(fileDeleted);
                                        Globals.Log.Add(LogLevel.Information, "Remote: Verzeichnis {0} wurde gelöscht (x-data).", relFilename);

                                        //In Created Verzeichnisse legen
                                        AddFileToUpdateFolder(client, "r-data", relFilename, EFileType.File);
                                    }
                                    else //File
                                    {
                                        //Hashdatei löchen
                                        RemoveHistoryHash(client, relFilename);
                                        Globals.Log.Add(LogLevel.Information, "Remote: Hash für {0} wurde gelöscht (x-data).", relFilename);

                                        //Datei löschen
                                        client.DeleteFile("x-data/"+relFilename);
                                        fileToRemoveFromList.Add(fileDeleted);
                                        Globals.Log.Add(LogLevel.Information, "Remote: Datei {0} wurde gelöscht (x-data).", relFilename);

                                        //In Created Verzeichnisse legen
                                        AddFileToUpdateFolder(client, "r-data", relFilename, EFileType.File);
                                    }
                                }

                                RemoveFileLock(client, relFilename);
                            }

                            foreach(string rFile in fileToRemoveFromList)
                            {
                                filesDeleted.Remove(rFile);
                            }
                        }

                        fileToRemoveFromList.Clear();
                        #endregion

                        //Neue Dateien herunterladen bzw. gelöscht Dateien löschen
                        UpdateFromRemote(client, syncFolder);

                        //Halbe Sekunde warten
                        Thread.Sleep(500);
                    }
                    #endregion

                    //string fileInfo=Globals.Options.GetElementAsString("xml.Sync.Filesystem.Test.txt");
                    //client.PutFile("D:\\AlexFTPS_bin_1.0.2.zip", "xxx.xxx");
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Schaut ob die Client Folder da sind bzw erstellt sie
        /// </summary>
        /// <param name="client"></param>
        /// <param name="dir"></param>
        public void CheckAndCreateClientFolder(FTPSClient client, string dir)
        {
            client.PushCurrentDirectory();
            client.SetCurrentDirectory(dir);

            IList<DirectoryListItem> files=client.GetDirectoryList();
            bool existClientDirectory=false;

            foreach(DirectoryListItem file in files)
            {
                if(file.IsDirectory)
                {
                    if(file.Name==Globals.ClientID)
                    {
                        existClientDirectory=true;
                    }
                }
            }

            if(existClientDirectory==false)
            {
                client.MakeDir(Globals.ClientID);
            }

            //client.SetCurrentDirectory("..");
            client.PopCurrentDirectory();
        }