Esempio n. 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");
                }
            }
        }
Esempio n. 2
0
        public void UpdateFromRemote(FTPSClient client, string syncFolder)
        {
            #region Removed
            List<FileReturn> filesToUpdate=GetFilesFromUpdateFolder(client, "r-data");

            if(filesToUpdate.Count>0)
            {
                foreach(FileReturn fileReturn in filesToUpdate)
                {
                    if(fileReturn.FileType==EFileType.File)
                    {
                        string localFilename=syncFolder+"/"+fileReturn.Filename;
                        FileSystem.RemoveFile(localFilename);
                        Globals.Log.Add(LogLevel.Information, "Lokal: Datei {0} wurde gelöscht (x-data).", fileReturn.Filename);
                    }
                    else if(fileReturn.FileType==EFileType.Directory)
                    {
                        throw new NotImplementedException();
                    }
                }
            }
            #endregion

            #region Created
            filesToUpdate=GetFilesFromUpdateFolder(client, "c-data");

            if(filesToUpdate.Count>0)
            {
                foreach(FileReturn fileReturn in filesToUpdate)
                {
                    if(fileReturn.FileType==EFileType.File)
                    {
                        string localFilename=syncFolder+"/"+fileReturn.Filename;
                        client.GetFile("x-data/"+fileReturn.Filename, localFilename);
                        Globals.Log.Add(LogLevel.Information, "Lokal: Datei {0} wurde erzeugt (x-data).", fileReturn.Filename);
                    }
                    else if(fileReturn.FileType==EFileType.Directory)
                    {
                        string localFilename=syncFolder+"/"+fileReturn.Filename;
                        client.GetFile("x-data/"+fileReturn.Filename, localFilename);
                        Globals.Log.Add(LogLevel.Information, "Lokal: Verzeichnis {0} wurde erzeugt (x-data).", fileReturn.Filename);
                    }
                }
            }
            #endregion

            #region Modified
            filesToUpdate=GetFilesFromUpdateFolder(client, "m-data");

            if(filesToUpdate.Count>0)
            {
                foreach(FileReturn fileReturn in filesToUpdate)
                {
                    if(fileReturn.FileType==EFileType.File)
                    {
                        string localFilename=syncFolder+"/"+fileReturn.Filename;
                        client.GetFile("x-data/"+fileReturn.Filename, localFilename);
                        Globals.Log.Add(LogLevel.Information, "Lokal: Datei {0} wurde modifiziert (x-data).", fileReturn.Filename);
                    }
                    else if(fileReturn.FileType==EFileType.Directory)
                    {
                        throw new NotImplementedException();
                    }
                }
            }
            #endregion
        }
Esempio n. 3
0
        public string GetHistoryHash(FTPSClient client, string relFilename)
        {
            string fileNameFTP=relFilename.Replace("/", "\\");
            fileNameFTP="h-data/"+fileNameFTP;

            if(client.Exists(fileNameFTP)) //Neuen Hash hinzufügen
            {
                string hashFilenameLocal=FileSystem.TempPath+FileSystem.GetFilename(fileNameFTP);
                client.GetFile(fileNameFTP, hashFilenameLocal);

                List<string> hashInfo=new List<string>();
                hashInfo.AddRange(File.ReadAllLines(hashFilenameLocal));

                return hashInfo[0];
            }
            else //keine Hashdatei vorhanden
            {
                return "";
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Gibt die Updatedateien eines Verzeichnisses zurück
        /// </summary>
        /// <param name="client"></param>
        /// <param name="folder"></param>
        /// <returns></returns>
        public List<FileReturn> GetFilesFromUpdateFolder(FTPSClient client, string folder)
        {
            List<FileReturn> ret=new List<FileReturn>();

            //In Update Verzeichniss legen
            string updateFolder=folder+"/"+Globals.ClientID+"/";
            IList<DirectoryListItem> updateFiles=client.GetDirectoryList(updateFolder); //TODO evt FTPException abfangen

            //Sicherheitspause falls gerade noch eine Datei angelegt wurde
            Thread.Sleep(500);

            //Updatedatei herunterladen und auswerten
            foreach(DirectoryListItem dli in updateFiles)
            {
                string filenameLocal=FileSystem.TempPath+dli.Name;
                client.GetFile(updateFolder+dli.Name, filenameLocal);

                string[] lines=File.ReadAllLines(filenameLocal);
                string filename=lines[0]; //Datei hinzufügen
                EFileType fileType=GetFileType(lines[1]);

                //Updatedatei löschen
                client.DeleteFile(updateFolder+dli.Name);
            }

            return ret;
        }
Esempio n. 5
0
        /// <summary>
        /// Holt einen Dateilock
        /// </summary>
        /// <param name="client"></param>
        /// <param name="file"></param>
        /// <returns></returns>
        public bool GetFileLock(FTPSClient client, string file)
        {
            file=file.Replace("/", "\\");
            file="l-data/"+file;

            if(client.Exists(file)) //Auf Lock überprüfen
            {
                Thread.Sleep(500);

                if(client.Exists(file)) //Nochmal Auf Lock überprüfen
                {
                    return false; //Lock konnte nicht geholt werden
                }
            }

            //Lock erzeugen
            string lockFilenameLocal=FileSystem.TempPath+FileSystem.GetFilename(file);
            string lockFilenameLocalCheck=FileSystem.TempPath+FileSystem.GetFilename(file)+".check";

            List<string> lines=new List<string>();
            lines.Add(Globals.ClientID);
            File.WriteAllLines(lockFilenameLocal, lines.ToArray());

            client.PutFile(lockFilenameLocal, file);

            //Lock überprüfen
            client.GetFile(file, lockFilenameLocalCheck);

            string[] linesLockFile=File.ReadAllLines(lockFilenameLocalCheck);
            string lockID=linesLockFile[0];

            if(Globals.ClientID==lockID) //Überprüfen ob das Lock ein Client Lock ist
            {
                return true;
            }
            else //Kein Client eigenes Lock
            {
                return false;
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Holt einen Dateilock
        /// </summary>
        /// <param name="client"></param>
        /// <param name="file"></param>
        /// <returns>true = New hash / </returns>
        public bool AddHistoryHash(FTPSClient client, string file, string relFilename)
        {
            string fileNameFTP=relFilename.Replace("/", "\\");
            fileNameFTP="h-data/"+fileNameFTP;

            string fileHash=Hash.SHA1.HashFile(file);

            if(client.Exists(fileNameFTP)) //Neuen Hash hinzufügen
            {
                string hashFilenameLocal=FileSystem.TempPath+FileSystem.GetFilename(fileNameFTP);
                client.GetFile(fileNameFTP, hashFilenameLocal);

                List<string> hashInfo=new List<string>();
                hashInfo.AddRange(File.ReadAllLines(hashFilenameLocal));

                if(hashInfo[0]==fileHash)
                {
                    return false;
                }
                else
                {
                    hashInfo.Add(fileHash);
                    File.WriteAllLines(hashFilenameLocal, hashInfo.ToArray());
                    client.PutFile(hashFilenameLocal, fileNameFTP);

                    return true;
                }
            }
            else //Hash Datei erzeugen
            {
                List<string> hashFile=new List<string>();
                hashFile.Add(fileHash); //Repository Version

                string hashFilenameLocal=FileSystem.TempPath+"hash-"+Various.GetTimeID();
                File.WriteAllLines(hashFilenameLocal, hashFile.ToArray());
                client.PutFile(hashFilenameLocal, fileNameFTP);

                return true;
            }
        }