Browse Source

Projektdateien hinzufügen.

Kolja Strohm 7 years ago
parent
commit
ebac442cdc

+ 12 - 0
Data/rsInit.ini

@@ -0,0 +1,12 @@
+DBBenutzer=registerserveru
+DBPasswort=LTRegisterServerPW
+DBName=test_db
+DBIP=127.0.0.1
+DBPort=5432
+ServerName=Test
+ServerPort=49148
+ServerIP=192.168.178.41
+AdminServerPort=49147
+Aktiv=FALSE
+MaxClients=50
+Java=C:/Program Files/Java/jre7/bin/java

+ 30 - 0
Register Server.sln

@@ -0,0 +1,30 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26020.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RegisterServer", "RegisterServer\RegisterServer.vcxproj", "{8D996790-9F3D-4C44-B541-9F14A44AB01F}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|ARM = Debug|ARM
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|ARM = Release|ARM
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8D996790-9F3D-4C44-B541-9F14A44AB01F}.Debug|ARM.ActiveCfg = Debug|x64
+		{8D996790-9F3D-4C44-B541-9F14A44AB01F}.Debug|x64.ActiveCfg = Debug|x64
+		{8D996790-9F3D-4C44-B541-9F14A44AB01F}.Debug|x64.Build.0 = Debug|x64
+		{8D996790-9F3D-4C44-B541-9F14A44AB01F}.Debug|x86.ActiveCfg = Debug|x64
+		{8D996790-9F3D-4C44-B541-9F14A44AB01F}.Release|ARM.ActiveCfg = Release|x64
+		{8D996790-9F3D-4C44-B541-9F14A44AB01F}.Release|x64.ActiveCfg = Release|x64
+		{8D996790-9F3D-4C44-B541-9F14A44AB01F}.Release|x64.Build.0 = Release|x64
+		{8D996790-9F3D-4C44-B541-9F14A44AB01F}.Release|x86.ActiveCfg = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 888 - 0
RegisterServer/Datenbank.cpp

@@ -0,0 +1,888 @@
+#include "Datenbank.h"
+#include <Datei.h>
+#include <iostream>
+#include <spawn.h>
+
+// Inhalt der RSDatenbank Klasse aus Datenbank.h
+// Konstruktor
+RSDatenbank::RSDatenbank( InitDatei *zIni )
+{
+    datenbank = new Datenbank( zIni->zWert( "DBBenutzer" )->getText(), zIni->zWert( "DBPasswort" )->getText(),
+        zIni->zWert( "DBName" )->getText(), zIni->zWert( "DBIP" )->getText(),
+        (unsigned short)TextZuInt( zIni->zWert( "DBPort" )->getText(), 10 ) );
+    if( !datenbank->istOk() )
+    {
+        std::cout << "AS: Die Verbindung zur Datenbank konnte nicht hergestellt werden.\nDas Programm wird beendet.";
+        exit( 1 );
+    }
+    InitializeCriticalSection( &cs );
+    ref = 1;
+    Text befehl = "SELECT port, admin_port  FROM server WHERE id = ";
+    befehl += zIni->zWert( "ServerId" )->getText();
+    lock();
+    datenbank->befehl( befehl );
+    Result res = datenbank->getResult();
+    unlock();
+    if( res.zeilenAnzahl == 1 )
+    {
+        zIni->addWert( "ServerPort", res.values[ 0 ] );
+        zIni->addWert( "AdminServerPort", res.values[ 1 ] );
+    }
+    res.destroy();
+}
+
+// Destruktor
+RSDatenbank::~RSDatenbank()
+{
+    datenbank->release();
+    DeleteCriticalSection( &cs );
+}
+
+// nicht constant
+void RSDatenbank::lock()
+{
+    EnterCriticalSection( &cs );
+}
+
+void RSDatenbank::unlock()
+{
+    LeaveCriticalSection( &cs );
+}
+
+int RSDatenbank::istAdministrator( const char *name, const char *passwort )
+{
+    Text *befehl = new Text( "SELECT id FROM benutzer WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "' AND passwort = md5( '" );
+    Text p( passwort );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' )" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    int ret = 0;
+    if( res.zeilenAnzahl > 0 )
+        ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+bool RSDatenbank::adminHatRecht( int id, int recht )
+{
+    Text *befehl = new Text( "SELECT * FROM benutzer_rechte WHERE benutzer_id = " );
+    befehl->append( id );
+    befehl->append( " AND rechte_id = " );
+    befehl->append( recht );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    int ret = datenbank->getZeilenAnzahl();
+    unlock();
+    befehl->release();
+    return ret != 0;
+}
+
+bool RSDatenbank::proveKlient( int num, int sNum )
+{
+    Text *befehl = new Text( "SELECT * FROM server_client WHERE server_register_id = " );
+    befehl->append( sNum );
+    befehl->append( " AND client_id = " );
+    befehl->append( num );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    bool ret = 0;
+    if( res.zeilenAnzahl == 1 )
+        ret = 1;
+    res.destroy();
+    return ret;
+}
+
+Text *RSDatenbank::getKlientKey( int cId )
+{
+    lock();
+    if( !datenbank->befehl( Text( "SELECT schluessel FROM client WHERE id = " ) += cId ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    Text *ret = new Text( res.values[ 0 ].getText() );
+    res.destroy();
+    return ret;
+}
+
+void RSDatenbank::unregisterKlient( int num, int sNum )
+{
+    Text *befehl = new Text( "DELETE FROM server_client WHERE client_id = " );
+    befehl->append( num );
+    befehl->append( " AND server_id = " );
+    befehl->append( sNum );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    int za = datenbank->getZeilenAnzahl();
+    unlock();
+    if( za == 1 )
+    {
+        befehl->setText( "UPDATE server SET tasks = tasks - 1 WHERE id = " );
+        befehl->append( sNum );
+        lock();
+        datenbank->befehl( befehl->getText() );
+        unlock();
+    }
+    befehl->release();
+}
+
+bool RSDatenbank::setServerStatus( int id, int status )
+{
+    Text *befehl = new Text( "UPDATE server SET server_status_id = " );
+    *befehl += status;
+    *befehl += "WHERE id = ";
+    *befehl += id;
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() != 0;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+bool RSDatenbank::setMaxClients( int id, int maxC )
+{
+    Text *befehl = new Text( "UPDATE server SET max_tasks = " );
+    befehl->append( maxC );
+    befehl->append( " WHERE id = " );
+    befehl->append( id );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() > 0;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+bool RSDatenbank::serverIstNichtPausiert( int id )
+{
+    Text *befehl = new Text( "SELECT server_status_id FROM server WHERE id = " );
+    befehl->append( id );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    bool ret = (int)res.values[ 0 ] == 3;
+    res.destroy();
+    return ret;
+}
+
+int RSDatenbank::proveNeuAccount( const char *name, const char *eMail )
+{
+    Text *befehl = new Text( "SELECT account_neu_alt_check( '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "', '" );
+    Text m( eMail );
+    m.ersetzen( "'", "''" );
+    befehl->append( (char*)m );
+    befehl->append( "' )" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    if( res.values[ 0 ].istGleich( "t" ) )
+    {
+        befehl->release();
+        res.destroy();
+        return 0;
+    }
+    else
+    {
+        res.destroy();
+        befehl->setText( "SELECT account.id FROM account, account_neu WHERE account.name = '" );
+        befehl->append( (char*)n );
+        befehl->append( "' OR account_neu.name = '" );
+        befehl->append( (char*)n );
+        befehl->append( "'" );
+        lock();
+        datenbank->befehl( befehl->getText() );
+        res = datenbank->getResult();
+        unlock();
+        if( res.zeilenAnzahl > 0 )
+        {
+            befehl->release();
+            res.destroy();
+            return 1;
+        }
+        else
+        {
+            res.destroy();
+            befehl->release();
+            return 2;
+        }
+    }
+}
+
+bool RSDatenbank::neuAccount( const char *name, const char *pass, const char *geheim, const char *eMail, const char *gebDatum, InitDatei *zIni )
+{
+    Text *befehl = new Text( "INSERT INTO account_neu( name, passwort, geheimnis, e_mail, geb_datum ) VALUES ( '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "', md5( '" );
+    Text p( pass );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' ), '" );
+    Text g( geheim );
+    g.ersetzen( "'", "''" );
+    befehl->append( (char*)g );
+    befehl->append( "', '" );
+    Text m( eMail );
+    m.ersetzen( "'", "''" );
+    befehl->append( (char*)m );
+    befehl->append( "', '" );
+    Text d( gebDatum );
+    d.ersetzen( "'", "''" );
+    befehl->append( (char*)d );
+    befehl->append( "' )" );
+    lock();
+    if( datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->setText( "SELECT schluessel FROM account_neu WHERE name = '" );
+        befehl->append( (char*)n );
+        befehl->append( "'" );
+        lock();
+        datenbank->befehl( befehl->getText() );
+        Result res = datenbank->getResult();
+        unlock();
+        Datei md;
+        if( res.zeilenAnzahl )
+        {
+            md.setDatei( res.values[ 0 ].getText() );
+            if( md.open( Datei::Style::schreiben ) )
+            {
+                md.schreibe( (char*)eMail, textLength( eMail ) );
+                md.schreibe( ( char* )"\nAccount freischalten\n", 22 );
+                md.schreibe( ( char* )"Dein Account Daten:\n", 20 );
+                md.schreibe( ( char* )"name: ", 6 );
+                md.schreibe( (char*)name, textLength( name ) );
+                md.schreibe( ( char* )"\npasswort: ", 11 );
+                md.schreibe( (char*)pass, textLength( pass ) );
+                md.schreibe( ( char* )"\ngeheimnis: ", 12 );
+                md.schreibe( (char*)geheim, textLength( geheim ) );
+                md.schreibe( ( char* )"\ngeburtsdatum: ", 15 );
+                md.schreibe( (char*)gebDatum, textLength( gebDatum ) );
+                md.schreibe( ( char* )"\naktivierungs key: ", 25 );
+                md.schreibe( res.values[ 0 ].getText(), res.values[ 0 ].getLength() );
+                md.close();
+                // e_mail senden
+                pid_t pid;
+                char *pargs[] = { zIni->zWert( "Java" )->getText(), zIni->zWert( "Mailer" )->getText(), res.values[ 0 ].getText(), (char*)0 };
+                posix_spawn( &pid, zIni->zWert( "Java" )->getText(), 0, 0, pargs, 0 );
+            }
+        }
+        res.destroy();
+        befehl->release();
+        return 1;
+    }
+    unlock();
+    befehl->release();
+    return 0;
+}
+
+void RSDatenbank::neuAccountAbbruch( const char *name )
+{
+    Text *befehl = new Text( "DELETE FROM account_neu WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "'" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    unlock();
+    befehl->release();
+}
+
+bool RSDatenbank::aktiviereAccount( const char *name, const char *key )
+{
+    Text *befehl = new Text( "SELECT account_aktivieren( '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "', '" );
+    Text s( key );
+    s.ersetzen( "'", "''" );
+    befehl->append( (char*)s );
+    befehl->append( "' )" );
+    lock();
+    if( datenbank->befehl( befehl->getText() ) )
+    {
+        befehl->release();
+        Result res = datenbank->getResult();
+        unlock();
+        if( res.values[ 0 ].istGleich( "f" ) )
+        {
+            res.destroy();
+            return 0;
+        }
+        return 1;
+    }
+    unlock();
+    befehl->release();
+    return 0;
+}
+
+int RSDatenbank::removeAccount( const char *name, const char *pass, const char *geheim, InitDatei *zIni )
+{
+    Text *befehl = new Text( "SELECT account_loeschen( '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "', md5( '" );
+    Text p( pass );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' ), '" );
+    Text g( geheim );
+    g.ersetzen( "'", "''" );
+    befehl->append( (char*)g );
+    befehl->append( "' )" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    if( !ret )
+    {
+        befehl->setText( "SELECT account_loeschen.schluessel, account.e_mail FROM account, account_loeschen WHERE account.id = account_loeschen.account_id AND account.name = '" );
+        befehl->append( (char*)n );
+        befehl->append( "'" );
+        lock();
+        datenbank->befehl( befehl->getText() );
+        res = datenbank->getResult();
+        unlock();
+        Datei md;
+        if( res.zeilenAnzahl )
+        {
+            md.setDatei( res.values[ 0 ].getText() );
+            if( md.open( Datei::Style::schreiben ) )
+            {
+                Text txt = res.values[ 1 ].getText();
+                txt += "\nAccount löschen\nSchade, dass du deinen Account löschen möchtest.\nBestätigungscode: ";
+                txt += res.values[ 0 ].getText();
+                md.schreibe( txt, txt.getLength() );
+                md.close();
+                // e_mail senden
+                pid_t pid;
+                char *pargs[] = { zIni->zWert( "Java" )->getText(), zIni->zWert( "Mailer" )->getText(), res.values[ 0 ].getText(), (char*)0 };
+                posix_spawn( &pid, zIni->zWert( "Java" )->getText(), 0, 0, pargs, 0 );
+            }
+        }
+        res.destroy();
+    }
+    befehl->release();
+    return ret;
+}
+
+void RSDatenbank::removeAccountAbbruch( const char *name )
+{
+    Text *befehl = new Text( "DELETE FROM account_loeschen WHERE account_id = ( SELECT id FROM account where name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "' )" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    unlock();
+    befehl->release();
+}
+
+bool RSDatenbank::removeConfirmation( const char *name, const char *key )
+{
+    Text *befehl = new Text( "SELECT account_loeschen_bestaetigen( '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "', '" );
+    Text s( key );
+    s.ersetzen( "'", "''" );
+    befehl->append( (char*)s );
+    befehl->append( "' )" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( res.values[ 0 ].istGleich( "t" ) )
+    {
+        res.destroy();
+        return 1;
+    }
+    res.destroy();
+    return 0;
+}
+
+int RSDatenbank::passwortChange( const char *name, const char *pass, const char *nPass, const char *geheim )
+{
+    Text * befehl = new Text( "SELECT id, passwort, geheimnis, md5( '" );
+    Text p( name );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' ) FROM account WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "'" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    if( res.zeilenAnzahl != 1 )
+    {
+        res.destroy();
+        befehl->release();
+        return 1;
+    }
+    if( !res.values[ 1 ].istGleich( res.values[ 3 ] ) )
+    {
+        res.destroy();
+        befehl->release();
+        return 2;
+    }
+    if( !res.values[ 2 ].istGleich( geheim ) )
+    {
+        res.destroy();
+        befehl->release();
+        return 3;
+    }
+    befehl->setText( "UPDATE account SET passwort = md5( '" );
+    p = Text( nPass );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' ) WHERE id = " );
+    befehl->append( res.values[ 0 ].getText() );
+    res.destroy();
+    lock();
+    datenbank->befehl( befehl->getText() );
+    unlock();
+    befehl->release();
+    return 0;
+}
+
+int RSDatenbank::eMailChange( const char *name, const char *pass, const char *geheim, const char *eMail )
+{
+    Text *befehl = new Text( "SELECT id, passwort, geheimnis, md5( '" );
+    Text p( name );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' ) FROM account WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "'" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    if( res.zeilenAnzahl != 1 )
+    {
+        res.destroy();
+        befehl->release();
+        return 1;
+    }
+    if( !res.values[ 1 ].istGleich( res.values[ 3 ] ) )
+    {
+        res.destroy();
+        befehl->release();
+        return 2;
+    }
+    if( !res.values[ 2 ].istGleich( geheim ) )
+    {
+        res.destroy();
+        befehl->release();
+        return 3;
+    }
+    befehl->setText( "Update account SET e_mail = '" );
+    Text m( eMail );
+    m.ersetzen( "'", "''" );
+    befehl->append( (char*)m );
+    befehl->append( "' WHERE id = " );
+    befehl->append( res.values[ 0 ].getText() );
+    res.destroy();
+    int ret = 0;
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+        ret = 4;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+int RSDatenbank::geheimnisChange( const char *name, const char *pass, const char *geheim, const char *nGeheim )
+{
+    Text * befehl = new Text( "SELECT id, passwort, geheimnis, md5( '" );
+    Text p( name );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' ) FROM account WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "'" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    if( res.zeilenAnzahl != 1 )
+    {
+        res.destroy();
+        befehl->release();
+        return 1;
+    }
+    if( !res.values[ 1 ].istGleich( res.values[ 3 ] ) )
+    {
+        res.destroy();
+        befehl->release();
+        return 2;
+    }
+    if( !res.values[ 2 ].istGleich( geheim ) )
+    {
+        res.destroy();
+        befehl->release();
+        return 3;
+    }
+    befehl->setText( "UPDATE account SET geheimnis = '" );
+    Text g( nGeheim );
+    g.ersetzen( "'", "''" );
+    befehl->append( (char*)g );
+    befehl->append( "' WHERE id = " );
+    befehl->append( res.values[ 0 ].getText() );
+    res.destroy();
+    lock();
+    datenbank->befehl( befehl->getText() );
+    unlock();
+    befehl->release();
+    return 0;
+}
+
+bool RSDatenbank::nameVergessen( const char *pass, const char *geheim, InitDatei *zIni )
+{
+    Text *befehl = new Text( "SELECT name, e_mail FROM account WHERE passwort = md5( '" );
+    Text p( pass );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' ) AND geheimnis = '" );
+    Text g( geheim );
+    g.ersetzen( "'", "''" );
+    befehl->append( (char*)g );
+    befehl->append( "'" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( res.zeilenAnzahl != 1 )
+    {
+        res.destroy();
+        return 0;
+    }
+    Datei md;
+    if( res.zeilenAnzahl )
+    {
+        Text pfad = res.values[ 0 ].getText();
+        pfad.ersetzen( " ", "_" );
+        pfad.insert( 0, "mail." );
+        md.setDatei( pfad );
+        if( md.open( Datei::Style::schreiben ) )
+        {
+            Text txt = res.values[ 1 ].getText();
+            txt += "\nAccount Name\nDein Account Name lautet: ";
+            txt += res.values[ 0 ].getText();
+            md.schreibe( txt, txt.getLength() );
+            md.close();
+            // e_mail senden
+            pid_t pid;
+            char *pargs[] = { zIni->zWert( "Java" )->getText(), zIni->zWert( "Mailer" )->getText(), pfad, (char*)0 };
+            posix_spawn( &pid, zIni->zWert( "Java" )->getText(), 0, 0, pargs, 0 );
+    }
+}
+    res.destroy();
+    return 1;
+}
+
+bool RSDatenbank::passwortVergessen( const char *name, const char *geheim, InitDatei *zIni )
+{
+    Text *befehl = new Text( "SELECT get_next_schluessel()" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->setText( "UPDATE account SET passwort = md5( '" );
+    Text pass( (char*)res.values[ 0 ] );
+    res.destroy();
+    befehl->append( (char*)pass );
+    befehl->append( "' ) WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "' AND geheimnis = '" );
+    Text g( geheim );
+    g.ersetzen( "'", "''" );
+    befehl->append( (char*)g );
+    befehl->append( "' RETURNING e_mail" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( res.zeilenAnzahl != 1 )
+    {
+        res.destroy();
+        return 0;
+    }
+    Datei md;
+    if( res.zeilenAnzahl )
+    {
+        Text pfad = res.values[ 0 ].getText();
+        pfad.ersetzen( " ", "_" );
+        pfad.insert( 0, "mail." );
+        md.setDatei( pfad );
+        if( md.open( Datei::Style::schreiben ) )
+        {
+            Text txt = res.values[ 1 ].getText();
+            txt += "\nAccount Passwort\nDein Account Passwort wurde zurückgesetzt und lautet jetzt: ";
+            txt += pass.getText();
+            md.schreibe( txt, txt.getLength() );
+            md.close();
+            // e_mail senden
+            pid_t pid;
+            char *pargs[] = { zIni->zWert( "Java" )->getText(), zIni->zWert( "Mailer" )->getText(), pfad, (char*)0 };
+            posix_spawn( &pid, zIni->zWert( "Java" )->getText(), 0, 0, pargs, 0 );
+    }
+}
+    res.destroy();
+    return 1;
+}
+
+bool RSDatenbank::geheimnisVergessen( const char *name, const char *pass, InitDatei *zIni )
+{
+    Text *befehl = new Text( "SELECT geheimnis, e_mail FROM account WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "' AND passwort = md5( '" );
+    Text p( pass );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' )" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( res.zeilenAnzahl != 1 )
+    {
+        res.destroy();
+        return 0;
+    }
+    Datei md;
+    if( res.zeilenAnzahl )
+    {
+        Text pfad = res.values[ 0 ].getText();
+        pfad.ersetzen( " ", "_" );
+        pfad.insert( 0, "mail." );
+        md.setDatei( pfad );
+        if( md.open( Datei::Style::schreiben ) )
+        {
+            Text txt = res.values[ 1 ].getText();
+            txt += "\nAccount Geheimnis\nDein Account Geheimnis lautet: ";
+            txt += res.values[ 0 ].getText();
+            md.schreibe( txt, txt.getLength() );
+            md.close();
+            // e_mail senden
+            pid_t pid;
+            char *pargs[] = { zIni->zWert( "Java" )->getText(), zIni->zWert( "Mailer" )->getText(), pfad, (char*)0 };
+            posix_spawn( &pid, zIni->zWert( "Java" )->getText(), 0, 0, pargs, 0 );
+    }
+}
+    res.destroy();
+    return 1;
+}
+
+Text *RSDatenbank::eMailVergessen( const char *name, const char *pass, const char *geheim )
+{
+    Text *befehl = new Text( "SELECT e_mail FROM account WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "' AND passwort = md5( '" );
+    Text p( pass );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' ) AND geheimnis = '" );
+    Text g( geheim );
+    g.ersetzen( "'", "''" );
+    befehl->append( (char*)g );
+    befehl->append( "'" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( res.zeilenAnzahl != 1 )
+    {
+        res.destroy();
+        return 0;
+    }
+    Text *ret = new Text( res.values[ 0 ].getText() );
+    res.destroy();
+    return ret;
+}
+
+char RSDatenbank::suchConfirmation( const char *name, const char *pass )
+{
+    Text *befehl = new Text( "select such_account_bestaetigung( '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "', '" );
+    Text p( pass );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' )" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    char ret = (char)TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+void RSDatenbank::sendeErstellEMail( const char *name, InitDatei *zIni )
+{
+    Text *befehl = new Text( "SELECT geheimnis, e_mail, geb_datum, schluessel FROM account_neu WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "'" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    Datei md;
+    if( res.zeilenAnzahl )
+    {
+        md.setDatei( res.values[ 3 ].getText() );
+        if( md.open( Datei::Style::schreiben ) )
+        {
+            Text txt = res.values[ 1 ].getText();
+            txt += "\nAccount freischalten\nDeine Account Daten:\n";
+            txt += "\r\nname: ";
+            txt += name;
+            txt += "\r\ngeheimnis: ";
+            txt += res.values[ 0 ].getText();
+            txt += "\r\ngeburtsdatum: ";
+            txt += res.values[ 2 ].getText();
+            txt += "\r\naktivierungs key: ";
+            txt += res.values[ 3 ].getText();
+            md.schreibe( txt, txt.getLength() );
+            md.close();
+            // e_mail senden
+            pid_t pid;
+            char *pargs[] = { zIni->zWert( "Java" )->getText(), zIni->zWert( "Mailer" )->getText(), res.values[ 4 ].getText(), (char*)0 };
+            posix_spawn( &pid, zIni->zWert( "Java" )->getText(), 0, 0, pargs, 0 );
+        }
+    }
+    res.destroy();
+}
+
+void RSDatenbank::sendeRemoveEMail( const char *name, InitDatei *zIni )
+{
+    Text *befehl = new Text( "SELECT account_loeschen.schluessel, account.e_mail FROM account, account_loeschen WHERE account.id = account_loeschen.account_id AND account.name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "'" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    Datei md;
+    if( res.zeilenAnzahl )
+    {
+        md.setDatei( res.values[ 0 ].getText() );
+        if( md.open( Datei::Style::schreiben ) )
+        {
+            Text txt = res.values[ 1 ].getText();
+            txt += "\nAccount löschen\nSchade, dass du deinen Account löschen möchtest.\nBestätigungscode: ";
+            txt += res.values[ 0 ].getText();
+            md.schreibe( txt, txt.getLength() );
+            md.close();
+            // e_mail senden
+            pid_t pid;
+            char *pargs[] = { zIni->zWert( "Java" )->getText(), zIni->zWert( "Mailer" )->getText(), res.values[ 0 ].getText(), (char*)0 };
+            posix_spawn( &pid, zIni->zWert( "Java" )->getText(), 0, 0, pargs, 0 );
+    }
+}
+    res.destroy();
+}
+
+// constant
+Text *RSDatenbank::getLetzterFehler() const
+{
+    return datenbank->getLetzterFehler();
+}
+
+// Reference Counting
+RSDatenbank *RSDatenbank::getThis()
+{
+    ref++;
+    return this;
+}
+
+RSDatenbank *RSDatenbank::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 66 - 0
RegisterServer/Datenbank.h

@@ -0,0 +1,66 @@
+#ifndef Datenbank_H
+#define Datenbank_H
+
+#include <sql.h>
+#include <Text.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+using namespace sql;
+
+namespace Admin_Recht
+{
+	const int RSStarten = 8;
+	const int RSBeenden = 9;
+	const int RSPausieren = 10;
+	const int RSMCChange = 11;
+}
+
+class RSDatenbank
+{
+private:
+	Datenbank *datenbank;
+	CRITICAL_SECTION cs;
+	int ref;
+
+public:
+	// Konstruktor
+	RSDatenbank( InitDatei *zIni );
+	// Destruktor
+	~RSDatenbank();
+	// nicht constant
+	void lock();
+	void unlock();
+	int istAdministrator( const char *name, const char *passwort );
+	bool adminHatRecht( int id, int recht );
+	bool proveKlient( int num, int sNum );
+	Text *getKlientKey( int cId );
+	void unregisterKlient( int num, int sNum );
+	bool setServerStatus( int id, int status );
+	bool setMaxClients( int id, int maxC );
+	bool serverIstNichtPausiert( int id );
+	int proveNeuAccount( const char *name, const char *eMail );
+	bool neuAccount( const char *name, const char *pass, const char *geheim, const char *eMail, const char *gebDatum, InitDatei *zIni );
+	void neuAccountAbbruch( const char *name );
+	bool aktiviereAccount( const char *name, const char *key );
+	int removeAccount( const char *name, const char *pass, const char *geheim, InitDatei *zIni );
+	void removeAccountAbbruch( const char *name );
+	bool removeConfirmation( const char *name, const char *key );
+	int passwortChange( const char *name, const char *pass, const char *nPass, const char *geheim );
+	int eMailChange( const char *name, const char *pass, const char *geheim, const char *eMail );
+	int geheimnisChange( const char *name, const char *pass, const char *geheim, const char *nGeheim );
+	bool nameVergessen( const char *pass, const char *geheim, InitDatei *zIni );
+	bool passwortVergessen( const char *name, const char *geheim, InitDatei *zIni );
+	bool geheimnisVergessen( const char *name, const char *pass, InitDatei *zIni );
+	Text *eMailVergessen( const char *name, const char *pass, const char *geheim );
+	char suchConfirmation( const char *name, const char *pass );
+	void sendeErstellEMail( const char *name, InitDatei *zIni );
+	void sendeRemoveEMail( const char *name, InitDatei *zIni );
+	// constant
+	Text *getLetzterFehler() const;
+	// Reference Counting
+	RSDatenbank *getThis();
+	RSDatenbank *release();
+};
+
+#endif

+ 1209 - 0
RegisterServer/RegisterServer.cpp

@@ -0,0 +1,1209 @@
+#include "RegisterServer.h"
+#include <iostream>
+#include <Klient.h>
+#include <Globals.h>
+
+// Inhalt der RegiserServer Klasse aus RegisterServer.h
+// Konstruktor 
+RegisterServer::RegisterServer( InitDatei *zIni )
+: Thread()
+{
+	Network::Start( 100 );
+	std::cout << "RS: Verbindung mit Datenbank wird hergestellt...\n";
+	db = new RSDatenbank( zIni );
+	klientAnzahl = 0;
+	klients = new RCArray< RSKlient >();
+	empfangen = 0;
+	gesendet = 0;
+	fehler = new Text();
+	ini = zIni->getThis();
+	id = *zIni->zWert( "ServerId" );
+	server = new Server();
+	aServer = new Server();
+	std::cout << "RS: Starten des Admin Servers...\n";
+	if( !aServer->verbinde( (unsigned short)TextZuInt( ini->zWert( "AdminServerPort" )->getText(), 10 ), 10 ) )
+	{
+		std::cout << "RS: Der Admin Server konnte nicht gestartet werden. Das Programm wird beendet.\n";
+		exit( 1 );
+	}
+	db->setServerStatus( id, 2 );
+	end = 0;
+	nichtPausiert = 0;
+	InitializeCriticalSection( &cs );
+	update = 0;
+	ref = 1;
+	if( zIni->zWert( "Aktiv" )->istGleich( "TRUE" ) )
+	{
+		serverStarten();
+		serverFortsetzen();
+	}
+}
+
+// Destruktor 
+RegisterServer::~RegisterServer()
+{
+	fehler->release();
+	server->trenne();
+	server->release();
+	aServer->trenne();
+	aServer->release();
+	if( klients )
+		klients->release();
+	ini->release();
+	db->release();
+	DeleteCriticalSection( &cs );
+}
+
+// nicht constant 
+void RegisterServer::runn()
+{
+	while( !end )
+	{
+		SKlient *klient;
+		klient = aServer->getKlient();
+		if( end && klient )
+		{
+			klient->trenne();
+			klient = klient->release();
+			Sleep( 1000 );
+			return;
+		}
+		if( !klient )
+			return;
+		RSAKlient *clHandle = new RSAKlient( klient, getThis() );
+		clHandle->start();
+	}
+}
+
+void RegisterServer::thread()
+{
+	while( 1 )
+	{
+		SKlient *klient;
+		klient = server->getKlient();
+		if( !klient )
+			break;
+		Framework::getThreadRegister()->cleanUpClosedThreads();
+		RSKlient *clHandle = new RSKlient( klient, getThis() );
+		EnterCriticalSection( &cs );
+		klients->set( clHandle, klientAnzahl );
+		klientAnzahl++;
+		LeaveCriticalSection( &cs );
+		clHandle->start();
+	}
+}
+
+void RegisterServer::close()
+{
+	db->setServerStatus( id, 1 );
+	server->trenne();
+#ifdef WIN32
+	warteAufThread( 1000 );
+#endif
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+		klients->z( i )->absturz();
+	klients = klients->release();
+	klientAnzahl = 0;
+	LeaveCriticalSection( &cs );
+	ende();
+	run = 0;
+	end = 1;
+	Klient *klient = new Klient();
+	klient->verbinde( aServer->getPort(), "127.0.0.1" );
+	Sleep( 500 );
+	aServer->trenne();
+	klient->release();
+}
+
+bool RegisterServer::serverStarten()
+{
+	if( nichtPausiert )
+	{
+		fehler->setText( "Der Server konnte nicht gestartet werden: Der Server läuft bereits." );
+		return 0;
+	}
+	if( server )
+		server->release();
+	server = new Server();
+	if( server->verbinde( (unsigned short)TextZuInt( ini->zWert( "ServerPort" )->getText(), 10 ), 10 ) )
+	{
+		nichtPausiert = 1;
+		start();
+		return 1;
+	}
+	else
+	{
+		serverBeenden();
+		fehler->setText( "Der Server konnte nicht gestartet werden: Eventuell ist der Port in benutzung." );
+		return 0;
+	}
+}
+
+bool RegisterServer::serverPause()
+{
+	if( !nichtPausiert )
+	{
+		fehler->setText( "Der Server konnte nicht pausiert werden: Der Server läuft nicht." );
+		return 0;
+	}
+	if( !db->setServerStatus( id, 2 ) )
+	{
+		fehler->setText( "Der Server konnte nicht pausiert werden: " );
+		fehler->append( db->getLetzterFehler() );
+		return 0;
+	}
+	return 1;
+}
+
+bool RegisterServer::serverFortsetzen()
+{
+	if( !nichtPausiert )
+	{
+		fehler->setText( "Der Server konnte nicht fortgesetzt werden: Der Server läuft nicht." );
+		return 0;
+	}
+	if( !db->setServerStatus( id, 3 ) )
+	{
+		fehler->setText( "Der Server konnte nicht fortgesetzt werden: " );
+		fehler->append( db->getLetzterFehler() );
+		return 0;
+	}
+	return 1;
+}
+
+bool RegisterServer::serverBeenden()
+{
+	if( !nichtPausiert )
+	{
+		fehler->setText( "Der Server konnte nicht beendet werden: Der Server läuft nicht." );
+		return 0;
+	}
+	if( db->serverIstNichtPausiert( id ) )
+	{
+		fehler->setText( "Der Server konnte nicht beendet werden: Der Server muss erst pausiert werden." );
+		return 0;
+	}
+	nichtPausiert = 0;
+	ende();
+	if( server )
+		server->trenne();
+	return 1;
+}
+
+bool RegisterServer::setMaxKlients( int mc )
+{
+	if( !db->setMaxClients( id, mc ) )
+	{
+		fehler->setText( "Die maximale Anzahl der Clients konnte nicht gesetzt werden:\n" );
+		fehler->append( db->getLetzterFehler() );
+		return 0;
+	}
+	ini->setWert( "MaxClients", Text() += mc );
+	return 1;
+}
+
+bool RegisterServer::absturzKlient( int klientId )
+{
+	bool gefunden = 0;
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+	{
+		if( klients->z( i )->getKlientNummer() == klientId )
+		{
+			klients->z( i )->absturz();
+			klients->remove( i );
+			klientAnzahl--;
+			gefunden = 1;
+			break;
+		}
+	}
+	LeaveCriticalSection( &cs );
+	return gefunden;
+}
+
+bool RegisterServer::removeKlient( RSKlient *zKlient )
+{
+	bool gefunden = 0;
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+	{
+		if( klients->z( i ) == zKlient )
+		{
+			klients->remove( i );
+			klientAnzahl--;
+			gefunden = 1;
+			break;
+		}
+	}
+	LeaveCriticalSection( &cs );
+	return gefunden;
+}
+
+void RegisterServer::addGesendet( int bytes )
+{
+	gesendet += bytes;
+}
+
+void RegisterServer::addEmpfangen( int bytes )
+{
+	empfangen += bytes;
+}
+
+// constant
+bool RegisterServer::istAn() const
+{
+	return db->serverIstNichtPausiert( id );
+}
+
+Server *RegisterServer::zServer() const
+{
+	return server;
+}
+
+RSDatenbank *RegisterServer::zDB() const
+{
+	return db;
+}
+
+bool RegisterServer::hatClients() const
+{
+	return klientAnzahl > 0;
+}
+
+int RegisterServer::getId() const
+{
+	return id;
+}
+
+char *RegisterServer::getLetzterFehler() const
+{
+	return fehler->getText();
+}
+
+InitDatei *RegisterServer::zIni() const
+{
+	return ini;
+}
+
+// Reference Counting
+RegisterServer *RegisterServer::getThis()
+{
+	ref++;
+	return this;
+}
+
+RegisterServer *RegisterServer::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der RSAKlient Klasse aus RegisterServer.h
+// Konstruktor 
+RSAKlient::RSAKlient( SKlient *klient, RegisterServer *rs )
+: Thread()
+{
+	this->klient = klient;
+	unsigned char key[ 20 ] = { 246, 1, 73, 51, 10, 103, 151, 180, 17, 220, 28, 241, 131, 229, 66, 137, 175, 218, 133, 58 };
+	klient->setSendeKey( (char*)key, 20 );
+	klient->setEmpfangKey( (char*)key, 20 );
+	name = new Text( "" );
+	passwort = new Text( "" );
+	adminId = 0;
+	version = 0;
+	this->rs = rs;
+}
+
+// Destruktor 
+RSAKlient::~RSAKlient()
+{
+	klient->trenne();
+	klient->release();
+	rs->release();
+	name->release();
+	passwort->release();
+}
+
+// nicht constant 
+void RSAKlient::thread()
+{
+	while( 1 )
+	{
+		char c = 0;
+		if( !klient->getNachrichtEncrypted( &c, 1 ) )
+			break;
+		else
+		{
+			bool br = 0;
+			switch( c )
+			{
+			case 1: // Login
+				if( 1 )
+				{
+					klient->sendeEncrypted( "\1", 1 );
+					char nLen = 0;
+					klient->getNachrichtEncrypted( &nLen, 1 );
+					char *n = new char[ nLen + 1 ];
+					n[ (int)nLen ] = 0;
+					if( nLen )
+						klient->getNachrichtEncrypted( n, nLen );
+					char pLen = 0;
+					klient->getNachrichtEncrypted( &pLen, 1 );
+					char *p = new char[ pLen + 1 ];
+					p[ (int)pLen ] = 0;
+					if( pLen )
+						klient->getNachrichtEncrypted( p, pLen );
+					int adminId = rs->zDB()->istAdministrator( n, p );
+					if( adminId )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						name->setText( n );
+						passwort->setText( p );
+						this->adminId = adminId;
+					}
+					else
+						errorZuKlient( "Falsche Kombination aus Name und Passwort." );
+					delete[] n;
+					delete[] p;
+				}
+				break;
+			case 2: // Logout
+				adminId = 0;
+				name->setText( "" );
+				passwort->setText( "" );
+				klient->sendeEncrypted( "\1", 1 );
+				break;
+			case 3: // Trennen
+				br = 1;
+				klient->sendeEncrypted( "\1", 1 );
+				break;
+			case 4: // Server starten
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					if( rs->zDB()->adminHatRecht( adminId, Admin_Recht::RSStarten ) )
+					{
+						if( !rs->serverStarten() )
+						{
+							Text *err = new Text();
+							err->append( rs->getLetzterFehler() );
+							errorZuKlient( err->getText() );
+							err->release();
+						}
+						else
+							klient->sendeEncrypted( "\1", 1 );
+					}
+					else
+						errorZuKlient( "Du bist nicht berechtigt den Server zu starten." );
+				}
+				break;
+			case 5: // Server beenden
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					if( rs->zDB()->adminHatRecht( adminId, Admin_Recht::RSBeenden ) )
+					{
+						if( rs->serverBeenden() )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							Text *err = new Text();
+							err->append( rs->getLetzterFehler() );
+							errorZuKlient( err->getText() );
+							err->release();
+						}
+					}
+					else
+						errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+				}
+				break;
+			case 6: // Programm Schließen
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					bool ok = 0;
+					if( rs->isRunning() )
+					{
+						if( rs->zDB()->adminHatRecht( adminId, Admin_Recht::RSBeenden ) )
+						{
+							if( rs->serverBeenden() )
+								ok = 1;
+							else
+							{
+								Text *err = new Text();
+								err->append( rs->getLetzterFehler() );
+								errorZuKlient( err->getText() );
+								err->release();
+							}
+						}
+						else
+							errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+					}
+					else
+						ok = 1;
+					if( ok && rs->hatClients() )
+					{
+						errorZuKlient( "Es sind noch Klients Online. Bitte versuche es später erneut." );
+						break;
+					}
+					if( ok )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						std::cout << "RS: Der Server wird von Benutzer " << adminId << " heruntergefahren.\n";
+						rs->close();
+						br = 1;
+					}
+				}
+				break;
+			case 7: // Progtamm abstürzen
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					bool ok = 0;
+					if( rs->isRunning() )
+					{
+						if( rs->zDB()->adminHatRecht( adminId, Admin_Recht::RSBeenden ) )
+						{
+							rs->serverBeenden();
+							ok = 1;
+						}
+						else
+							errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+					}
+					else
+						ok = 1;
+					if( ok )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						std::cout << "RS: Der Server wurde von Benutzer " << adminId << " terminiert.\n";
+						rs->close();
+						br = 1;
+					}
+				}
+				break;
+			case 8: // Status Frage
+				if( 1 )
+				{
+					char status = 0;
+					if( rs->isRunning() )
+					{
+						status = 1;
+						if( rs->istAn() )
+							status = 2;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					klient->sendeEncrypted( &status, 1 );
+				}
+				break;
+			case 9: // Server pausieren
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					klient->sendeEncrypted( "\1", 1 );
+					char pause = 0;
+					klient->getNachrichtEncrypted( &pause, 1 );
+					if( rs->zDB()->adminHatRecht( adminId, Admin_Recht::RSPausieren ) )
+					{
+						bool ok = 0;
+						if( pause )
+							ok = rs->serverPause();
+						else
+							ok = rs->serverFortsetzen();
+						if( ok )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							Text *err = new Text();
+							err->append( rs->getLetzterFehler() );
+							errorZuKlient( err->getText() );
+							err->release();
+						}
+					}
+					else
+					{
+						if( pause )
+							errorZuKlient( "Du bist nicht berechtigt den Server zu pausieren." );
+						else
+							errorZuKlient( "Du bist nicht berechtigt den Server fortzusetzen." );
+					}
+				}
+				break;
+			case 0xA: // maximale Anzahl der Clients setzen
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					klient->sendeEncrypted( "\1", 1 );
+					int maxC = 0;
+					klient->getNachrichtEncrypted( (char*)&maxC, 4 );
+					if( rs->zDB()->adminHatRecht( adminId, Admin_Recht::RSMCChange ) )
+					{
+						if( rs->setMaxKlients( maxC ) )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							Text *err = new Text();
+							err->append( rs->getLetzterFehler() );
+							errorZuKlient( err->getText() );
+							err->release();
+						}
+					}
+					else
+						errorZuKlient( "Du bist nicht berechtigt die maximale Anzahl der Clients zu verändern." );
+				}
+				break;
+            case 0xC: // klient absturtz
+                if( 1 )
+                {
+                    klient->sendeEncrypted( "\1", 1 );
+                    int klientId = 0;
+                    klient->getNachrichtEncrypted( (char*)&klientId, 4 );
+                    if( klientId && rs->absturzKlient( klientId ) )
+                        klient->sendeEncrypted( "\1", 1 );
+                    else
+                        klient->sendeEncrypted( "\0", 1 );
+                }
+                break;
+			default:
+				errorZuKlient( "Unbekannte Nachricht!" );
+				break;
+			}
+			if( br )
+				break;
+			rs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			rs->addGesendet( klient->getUploadBytes( 1 ) );
+		}
+	}
+	rs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	rs->addGesendet( klient->getUploadBytes( 1 ) );
+	delete this;
+}
+
+void RSAKlient::errorZuKlient( const char *nachricht ) const // sendet eine Fehlernachricht zum Klient
+{
+	klient->sendeEncrypted( "\3", 1 );
+	char len = (char)textLength( nachricht );
+	klient->sendeEncrypted( &len, 1 );
+	klient->sendeEncrypted( nachricht, len );
+}
+
+
+// Inhalt der RSKlasse aus RegisterServer.h
+// Konstruktor 
+RSKlient::RSKlient( SKlient *klient, RegisterServer *rs )
+: Thread()
+{
+	this->klient = klient;
+	unsigned char key[ 20 ] = { 186, 186, 179, 126, 216, 207, 123, 154, 168, 149, 51, 221, 6, 193, 160, 141, 164, 126, 44, 242 };
+	klient->setSendeKey( (char*)key, 20 );
+	klient->setEmpfangKey( (char*)key, 20 );
+	klientNummer = 0;
+	this->rs = rs;
+	ref = 1;
+}
+
+// Destruktor 
+RSKlient::~RSKlient()
+{
+	klient->release();
+	rs->release();
+}
+
+// nicht constant
+void RSKlient::absturz()
+{
+	ende();
+	klient->trenne();
+	rs->zDB()->unregisterKlient( klientNummer, rs->getId() );
+}
+
+void RSKlient::thread()
+{
+	while( 1 )
+	{
+		char c = 0;
+		if( !klient->getNachrichtEncrypted( &c, 1 ) )
+			break;
+		else
+		{
+			bool br = 0;
+			switch( c )
+			{
+			case 1: // Klient identifikation
+				klient->getNachrichtEncrypted( (char*)&klientNummer, 4 );
+				if( !rs->zDB()->proveKlient( klientNummer, rs->getId() ) )
+				{
+					klientNummer = 0;
+					errorZuKlient( "Du bist nicht für diesen Server eingetragen" );
+				}
+				else
+				{
+					Text *key = rs->zDB()->getKlientKey( klientNummer );
+					if( !key )
+						errorZuKlient( "Es konnte kein Key ermittelt werden." );
+					else
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						klient->setEmpfangKey( *key, key->getLength() );
+						klient->setSendeKey( *key, key->getLength() );
+						key->release();
+					}
+				}
+				break;
+			case 2: // Main / Erhaltung Server message
+				if( 1 )
+				{
+					char befehl = 0;
+					klient->getNachrichtEncrypted( &befehl, 1 );
+					switch( befehl )
+					{
+					case 2: // klient absturtz
+						if( 1 )
+						{
+							int klientId = 0;
+							klient->getNachrichtEncrypted( (char*)&klientId, 4 );
+							if( klientId && rs->absturzKlient( klientId ) )
+								klient->sendeEncrypted( "\1", 1 );
+							else
+								klient->sendeEncrypted( "\0", 1 );
+						}
+						break;
+					default:
+						errorZuKlient( "Befehl nicht bekannt!" );
+						break;
+					}
+				}
+				break;
+			case 3: // Verbindungsende
+				br = 1;
+				klient->sendeEncrypted( "\1", 1 );
+				break;
+			case 4: // unregister Klient
+				if( !klientNummer )
+				{
+					errorZuKlient( "Du bist nicht Identifiziert." );
+					break;
+				}
+				rs->zDB()->unregisterKlient( klientNummer, rs->getId() );
+				klient->sendeEncrypted( "\1", 1 );
+				break;
+			case 5: // Account erstellen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					unsigned char len[ 4 ] = { 0, 0, 0, 0 };
+					klient->getNachrichtEncrypted( (char*)len, 4 );
+					char *acc_name = new char[ len[ 0 ] + 1 ];
+					acc_name[ len[ 0 ] ] = 0;
+					klient->getNachrichtEncrypted( acc_name, len[ 0 ] );
+					char *acc_pass = new char[ len[ 1 ] + 1 ];
+					acc_pass[ len[ 1 ] ] = 0;
+					klient->getNachrichtEncrypted( acc_pass, len[ 1 ] );
+					char *acc_geheim = new char[ len[ 2 ] + 1 ];
+					acc_geheim[ len[ 2 ] ] = 0;
+					klient->getNachrichtEncrypted( acc_geheim, len[ 2 ] );
+					char *acc_mail = new char[ len[ 3 ] + 1 ];
+					acc_mail[ len[ 3 ] ] = 0;
+					klient->getNachrichtEncrypted( acc_mail, len[ 3 ] );
+					unsigned short acc_geb_jahr = 0;
+					klient->getNachrichtEncrypted( (char*)&acc_geb_jahr, 2 );
+					char acc_geb_monat = 0;
+					klient->getNachrichtEncrypted( &acc_geb_monat, 1 );
+					char acc_geb_tag = 0;
+					klient->getNachrichtEncrypted( &acc_geb_tag, 1 );
+					int pres = rs->zDB()->proveNeuAccount( acc_name, acc_mail );
+					if( !pres )
+					{
+						Text *gebDatum = new Text( "" );
+						gebDatum->append( (int)acc_geb_jahr );
+						gebDatum->append( "-" );
+						gebDatum->append( (int)acc_geb_monat );
+						gebDatum->append( "-" );
+						gebDatum->append( (int)acc_geb_tag );
+						if( !rs->zDB()->neuAccount( acc_name, acc_pass, acc_geheim, acc_mail, gebDatum->getText(), rs->zIni() ) )
+						{
+							Text *err = new Text( "Das Datum '" );
+							err->append( gebDatum->getText() );
+							err->append( "' ist kein gültiges Datum." );
+							errorZuKlient( err->getText() );
+							err->release();
+						}
+						else
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							while( 1 )
+							{
+								char len = 0;
+								klient->getNachrichtEncrypted( &len, 1 );
+								if( !len ) // abbruch
+								{
+									rs->zDB()->neuAccountAbbruch( acc_name );
+									break;
+								}
+								if( len == -1 )
+									break;
+								char *key = new char[ len + 1 ];
+								key[ (int)len ] = 0;
+								klient->getNachrichtEncrypted( key, len );
+								if( rs->zDB()->aktiviereAccount( acc_name, key ) )
+								{
+									klient->sendeEncrypted( "\1", 1 );
+									delete[]key;
+									break;
+								}
+								else
+									klient->sendeEncrypted( "\0", 1 );
+								delete[]key;
+							}
+						}
+						gebDatum->release();
+					}
+					else
+					{
+						if( pres == 1 )
+							errorZuKlient( "Der Name wird bereits verwendet." );
+						else if( pres == 2 )
+							errorZuKlient( "Die E-Mail Adresse wird bereits verwendet." );
+					}
+					delete[]acc_name;
+					delete[]acc_pass;
+					delete[]acc_geheim;
+					delete[]acc_mail;
+				}
+				break;
+			case 6: // Account removen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					char len[ 3 ];
+					klient->getNachrichtEncrypted( len, 3 );
+					char *acc_name = new char[ len[ 0 ] + 1 ];
+					acc_name[ (int)len[ 0 ] ] = 0;
+					klient->getNachrichtEncrypted( acc_name, len[ 0 ] );
+					char *acc_pass = new char[ len[ 1 ] + 1 ];
+					acc_pass[ (int)len[ 1 ] ] = 0;
+					klient->getNachrichtEncrypted( acc_pass, len[ 1 ] );
+					char *acc_geheim = new char[ len[ 2 ] + 1 ];
+					acc_geheim[ (int)len[ 2 ] ] = 0;
+					klient->getNachrichtEncrypted( acc_geheim, len[ 2 ] );
+					int res = rs->zDB()->removeAccount( acc_name, acc_pass, acc_geheim, rs->zIni() );
+					if( !res )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						while( 1 )
+						{
+							char len = 0;
+							klient->getNachrichtEncrypted( &len, 1 );
+							if( !len )
+							{
+								rs->zDB()->removeAccountAbbruch( acc_name );
+								break;
+							}
+							if( len == -1 )
+								break;
+							char *key = new char[ len + 1 ];
+							key[ (int)len ] = 0;
+							klient->getNachrichtEncrypted( key, len );
+							if( rs->zDB()->removeConfirmation( acc_name, key ) )
+							{
+								klient->sendeEncrypted( "\1", 1 );
+								delete[]key;
+								break;
+							}
+							else
+								klient->sendeEncrypted( "\0", 1 );
+							delete[]key;
+						}
+					}
+					else if( res == 1 )
+						errorZuKlient( "Der Account wurde nicht gefunden." );
+					else if( res == 2 )
+						errorZuKlient( "Falsches Passwort." );
+					else if( res == 3 )
+						errorZuKlient( "Falsches Geheimnis." );
+					delete[]acc_name;
+					delete[]acc_pass;
+					delete[]acc_geheim;
+				}
+				break;
+			case 7: // Passwort ändern
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					unsigned char len[ 4 ];
+					klient->getNachrichtEncrypted( (char*)len, 4 );
+					char *accName = new char[ len[ 0 ] + 1 ];
+					accName[ len[ 0 ] ] = 0;
+					klient->getNachrichtEncrypted( accName, len[ 0 ] );
+					char *accPasswort = new char[ len[ 1 ] + 1 ];
+					accPasswort[ len[ 1 ] ] = 0;
+					klient->getNachrichtEncrypted( accPasswort, len[ 1 ] );
+					char *neuPasswort = new char[ len[ 2 ] + 1 ];
+					neuPasswort[ len[ 2 ] ] = 0;
+					klient->getNachrichtEncrypted( neuPasswort, len[ 2 ] );
+					char *accGeheimnis = new char[ len[ 3 ] + 1 ];
+					accGeheimnis[ len[ 3 ] ] = 0;
+					klient->getNachrichtEncrypted( accGeheimnis, len[ 3 ] );
+					int res = rs->zDB()->passwortChange( accName, accPasswort, neuPasswort, accGeheimnis );
+					if( !res )
+						klient->sendeEncrypted( "\1", 1 );
+					else if( res == 1 )
+						errorZuKlient( "Account nicht gefunden." );
+					else if( res == 2 )
+						errorZuKlient( "Falsches Passwort." );
+					else if( res == 3 )
+						errorZuKlient( "Falsches Geheimnis." );
+					delete[]accName;
+					delete[]accPasswort;
+					delete[]neuPasswort;
+					delete[]accGeheimnis;
+				}
+				break;
+			case 8: // E-Mail ändern
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					unsigned char len[ 4 ];
+					klient->getNachrichtEncrypted( (char*)len, 4 );
+					char *accName = new char[ len[ 0 ] + 1 ];
+					accName[ len[ 0 ] ] = 0;
+					klient->getNachrichtEncrypted( accName, len[ 0 ] );
+					char *accPasswort = new char[ len[ 1 ] + 1 ];
+					accPasswort[ len[ 1 ] ] = 0;
+					klient->getNachrichtEncrypted( accPasswort, len[ 1 ] );
+					char *accGeheimnis = new char[ len[ 2 ] + 1 ];
+					accGeheimnis[ len[ 2 ] ] = 0;
+					klient->getNachrichtEncrypted( accGeheimnis, len[ 2 ] );
+					char *neuEMail = new char[ len[ 3 ] + 1 ];
+					neuEMail[ len[ 3 ] ] = 0;
+					klient->getNachrichtEncrypted( neuEMail, len[ 3 ] );
+					int res = rs->zDB()->eMailChange( accName, accPasswort, accGeheimnis, neuEMail );
+					if( !res )
+						klient->sendeEncrypted( "\1", 1 );
+					else if( res == 1 )
+						errorZuKlient( "Account nicht gefunden." );
+					else if( res == 2 )
+						errorZuKlient( "Falsches Passwort." );
+					else if( res == 3 )
+						errorZuKlient( "Falsches Geheimnis." );
+					else if( res == 4 )
+						errorZuKlient( "Diese E-Mail Addresse wird bereits verwendet." );
+					delete[]accName;
+					delete[]accPasswort;
+					delete[]accGeheimnis;
+					delete[]neuEMail;
+				}
+				break;
+			case 9: // Geheimnis Ändern
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					unsigned char len[ 4 ];
+					klient->getNachrichtEncrypted( (char*)len, 4 );
+					char *accName = new char[ len[ 0 ] + 1 ];
+					accName[ len[ 0 ] ] = 0;
+					klient->getNachrichtEncrypted( accName, len[ 0 ] );
+					char *accPasswort = new char[ len[ 1 ] + 1 ];
+					accPasswort[ len[ 1 ] ] = 0;
+					klient->getNachrichtEncrypted( accPasswort, len[ 1 ] );
+					char *accGeheimnis = new char[ len[ 2 ] + 1 ];
+					accGeheimnis[ len[ 2 ] ] = 0;
+					klient->getNachrichtEncrypted( accGeheimnis, len[ 2 ] );
+					char *neuGeheimnis = new char[ len[ 3 ] + 1 ];
+					neuGeheimnis[ len[ 3 ] ] = 0;
+					klient->getNachrichtEncrypted( neuGeheimnis, len[ 3 ] );
+					int res = rs->zDB()->geheimnisChange( accName, accPasswort, accGeheimnis, neuGeheimnis );
+					if( !res )
+						klient->sendeEncrypted( "\1", 1 );
+					else if( res == 1 )
+						errorZuKlient( "Account nicht gefunden." );
+					else if( res == 2 )
+						errorZuKlient( "Falsches Passwort." );
+					else if( res == 3 )
+						errorZuKlient( "Falsches Geheimnis." );
+					delete[]accName;
+					delete[]accPasswort;
+					delete[]accGeheimnis;
+					delete[]neuGeheimnis;
+				}
+				break;
+			case 0xA: // Name Vergessen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					unsigned char len[ 2 ];
+					klient->getNachrichtEncrypted( (char*)len, 2 );
+					char *accPasswort = new char[ len[ 0 ] + 1 ];
+					accPasswort[ len[ 0 ] ] = 0;
+					klient->getNachrichtEncrypted( accPasswort, len[ 0 ] );
+					char *accGeheimnis = new char[ len[ 1 ] + 1 ];
+					accGeheimnis[ len[ 1 ] ] = 0;
+					klient->getNachrichtEncrypted( accGeheimnis, len[ 1 ] );
+					if( rs->zDB()->nameVergessen( accPasswort, accGeheimnis, rs->zIni() ) )
+						klient->sendeEncrypted( "\1", 1 );
+					else
+						errorZuKlient( "Account nicht gefunden." );
+					delete[]accPasswort;
+					delete[]accGeheimnis;
+				}
+				break;
+			case 0xB: // Passwort Vergessen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					unsigned char len[ 2 ];
+					klient->getNachrichtEncrypted( (char*)len, 2 );
+					char *accName = new char[ len[ 0 ] + 1 ];
+					accName[ len[ 0 ] ] = 0;
+					klient->getNachrichtEncrypted( accName, len[ 0 ] );
+					char *accGeheimnis = new char[ len[ 1 ] + 1 ];
+					accGeheimnis[ len[ 1 ] ] = 0;
+					klient->getNachrichtEncrypted( accGeheimnis, len[ 1 ] );
+					if( rs->zDB()->passwortVergessen( accName, accGeheimnis, rs->zIni() ) )
+						klient->sendeEncrypted( "\1", 1 );
+					else
+						errorZuKlient( "Account nicht gefunden." );
+					delete[]accName;
+					delete[]accGeheimnis;
+				}
+				break;
+			case 0xC: // Geheimnis Vergessen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					unsigned char len[ 2 ];
+					klient->getNachrichtEncrypted( (char*)len, 2 );
+					char *accName = new char[ len[ 0 ] + 1 ];
+					accName[ len[ 0 ] ] = 0;
+					klient->getNachrichtEncrypted( accName, len[ 0 ] );
+					char *accPasswort = new char[ len[ 1 ] + 1 ];
+					accPasswort[ len[ 1 ] ] = 0;
+					klient->getNachrichtEncrypted( accPasswort, len[ 1 ] );
+					if( rs->zDB()->geheimnisVergessen( accName, accPasswort, rs->zIni() ) )
+						klient->sendeEncrypted( "\1", 1 );
+					else
+						errorZuKlient( "Account nicht gefunden." );
+					delete[]accName;
+					delete[]accPasswort;
+				}
+				break;
+			case 0xD: // E-Mail Vergessen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					unsigned char len[ 3 ];
+					klient->getNachrichtEncrypted( (char*)len, 3 );
+					char *accName = new char[ len[ 0 ] + 1 ];
+					accName[ len[ 0 ] ] = 0;
+					klient->getNachrichtEncrypted( accName, len[ 0 ] );
+					char *accPasswort = new char[ len[ 1 ] + 1 ];
+					accPasswort[ len[ 1 ] ] = 0;
+					klient->getNachrichtEncrypted( accPasswort, len[ 1 ] );
+					char *accGeheimnis = new char[ len[ 2 ] + 1 ];
+					accGeheimnis[ len[ 2 ] ] = 0;
+					klient->getNachrichtEncrypted( accGeheimnis, len[ 2 ] );
+					Text *eMail = rs->zDB()->eMailVergessen( accName, accPasswort, accGeheimnis );
+					if( eMail )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						unsigned char len = (unsigned char)eMail->getLength();
+						klient->sendeEncrypted( (char*)&len, 1 );
+						klient->sendeEncrypted( eMail->getText(), len );
+						eMail->release();
+					}
+					else
+						errorZuKlient( "Account nicht gefunden." );
+					delete[]accName;
+					delete[]accPasswort;
+					delete[]accGeheimnis;
+				}
+				break;
+			case 0xE: // Account bestätigen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					unsigned char len[ 2 ];
+					klient->getNachrichtEncrypted( (char*)len, 2 );
+					char *accName = new char[ len[ 0 ] + 1 ];
+					accName[ len[ 0 ] ] = 0;
+					klient->getNachrichtEncrypted( accName, len[ 0 ] );
+					char *accPasswort = new char[ len[ 1 ] + 1 ];
+					accPasswort[ len[ 1 ] ] = 0;
+					klient->getNachrichtEncrypted( accPasswort, len[ 1 ] );
+					char byte = rs->zDB()->suchConfirmation( accName, accPasswort );
+					if( !byte )
+						errorZuKlient( "Bei diesem Account ist keine Bestätigung notwendig." );
+					else if( byte == -1 )
+						errorZuKlient( "Falsche Kombination von Name und Passwort." );
+					else if( byte > 0 )
+					{
+						klient->sendeEncrypted( &byte, 1 );
+						char befehl = 0;
+						while( 1 )
+						{
+							klient->getNachrichtEncrypted( &befehl, 1 );
+							if( !befehl )
+							{
+								if( byte == 1 )
+									rs->zDB()->neuAccountAbbruch( accName );
+								if( byte == 2 )
+									rs->zDB()->removeAccountAbbruch( accName );
+								break;
+							}
+							if( befehl == -1 )
+								break;
+							if( befehl == -2 )
+							{
+								if( byte == 1 )
+									rs->zDB()->sendeErstellEMail( accName, rs->zIni() );
+								if( byte == 2 )
+									rs->zDB()->sendeRemoveEMail( accName, rs->zIni() );
+							}
+							if( befehl > 0 )
+							{
+								char *key = new char[ befehl + 1 ];
+								key[ (int)befehl ] = 0;
+								klient->getNachrichtEncrypted( key, befehl );
+								if( byte == 1 )
+								{
+									if( !rs->zDB()->aktiviereAccount( accName, key ) )
+										klient->sendeEncrypted( "\0", 1 );
+									else
+									{
+										klient->sendeEncrypted( "\1", 1 );
+										delete[]key;
+										break;
+									}
+								}
+								if( byte == 2 )
+								{
+									if( !rs->zDB()->removeConfirmation( accName, key ) )
+										klient->sendeEncrypted( "\0", 1 );
+									else
+									{
+										klient->sendeEncrypted( "\1", 1 );
+										delete[]key;
+										break;
+									}
+								}
+								delete[]key;
+							}
+						}
+					}
+					delete[]accName;
+					delete[]accPasswort;
+				}
+				break;
+			case 0xF: // ping
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+				}
+				break;
+			default:
+				errorZuKlient( "Unbekannte Nachricht!" );
+				break;
+			}
+			if( br )
+				break;
+		}
+		rs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+		rs->addGesendet( klient->getUploadBytes( 1 ) );
+	}
+	rs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	rs->addGesendet( klient->getUploadBytes( 1 ) );
+	rs->removeKlient( this ); // delete this
+}
+
+// constant
+void RSKlient::errorZuKlient( const char *nachricht ) const // sendet eine Fehlernachricht zum Klient
+{
+	klient->sendeEncrypted( "\3", 1 );
+	char len = (char)textLength( nachricht );
+	klient->sendeEncrypted( &len, 1 );
+	klient->sendeEncrypted( nachricht, len );
+}
+
+int RSKlient::getKlientNummer() const // gibt die KlientId zurück
+{
+	return klientNummer;
+}
+
+// Reference Counting
+RSKlient *RSKlient::getThis()
+{
+	ref++;
+	return this;
+}
+
+RSKlient *RSKlient::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 110 - 0
RegisterServer/RegisterServer.h

@@ -0,0 +1,110 @@
+#ifndef RegisterServer_H
+#define RegisterServer_H
+
+#include "Datenbank.h"
+#include <Server.h>
+#include <Thread.h>
+#include <Datei.h>
+#include <Text.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+using namespace Network;
+
+class RSKlient;
+
+class RegisterServer : public Thread
+{
+private:
+	Server *server;
+	Server *aServer;
+	InitDatei *ini;
+	RSDatenbank *db;
+	CRITICAL_SECTION cs;
+	RCArray< RSKlient > *klients;
+	Text *fehler;
+	int klientAnzahl;
+	int id;
+	bool nichtPausiert;
+	int empfangen;
+	int gesendet;
+	bool update;
+	bool end;
+	int ref;
+
+public:
+	// Konstruktor 
+	RegisterServer( InitDatei *zIni );
+	// Destruktor 
+	virtual ~RegisterServer();
+	// nicht constant 
+	void runn();
+	void thread();
+	void close();
+	bool serverStarten();
+	bool serverPause();
+	bool serverFortsetzen();
+	bool serverBeenden();
+	bool setMaxKlients( int mc );
+	bool absturzKlient( int klientId );
+	bool removeKlient( RSKlient *zKlient );
+	void addGesendet( int bytes );
+	void addEmpfangen( int bytes );
+	// conatant 
+	bool istAn() const;
+	Server *zServer() const;
+	RSDatenbank *zDB() const;
+	bool hatClients() const;
+	int getId() const;
+	char *getLetzterFehler() const;
+	InitDatei *zIni() const;
+	// Reference Counting
+	RegisterServer *getThis();
+	RegisterServer *release();
+};
+
+class RSAKlient : public Thread
+{
+private:
+	SKlient *klient;
+	Text *name;
+	Text *passwort;
+	int adminId;
+	RegisterServer *rs;
+	int version;
+
+public:
+	// Konstruktor 
+	RSAKlient( SKlient *klient, RegisterServer *rs );
+	// Destruktor 
+	virtual ~RSAKlient();
+	// nicht constant
+	void thread();
+	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum AKlient
+};
+
+class RSKlient : public Thread
+{
+private:
+	SKlient      *klient;
+	unsigned int klientNummer;
+	RegisterServer *rs;
+	int ref;
+
+public:
+	// Konstruktor 
+	RSKlient( SKlient *klient, RegisterServer *rs );
+	// Destruktor 
+	virtual ~RSKlient();
+	// nicht constant
+	void absturz();
+	void thread();
+	// constant
+	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum Klient
+	int getKlientNummer() const;
+	// Reference Counting
+	RSKlient *getThis();
+	RSKlient *release();
+};
+
+#endif

+ 72 - 0
RegisterServer/RegisterServer.vcxproj

@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{8d996790-9f3d-4c44-b541-9f14a44ab01f}</ProjectGuid>
+    <Keyword>Linux</Keyword>
+    <RootNamespace>RegisterServer</RootNamespace>
+    <MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
+    <ApplicationType>Linux</ApplicationType>
+    <ApplicationTypeRevision>1.0</ApplicationTypeRevision>
+    <TargetLinuxPlatform>Generic</TargetLinuxPlatform>
+    <LinuxProjectType>{D51BCBC9-82E9-4017-911E-C93873C4EA2B}</LinuxProjectType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <RemoteRootDir>/home/kolja/projects</RemoteRootDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <RemoteRootDir>/home/kolja/projects</RemoteRootDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Label="Shared" />
+  <ImportGroup Label="PropertySheets" />
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetExt />
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/Debug</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;../../../Framework/Debug;..\..\..\..\Allgemein\Network\Network;../../../Network/Debug;..\..\..\..\Allgemein\sql\sql;../../../sql/Debug;$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetExt />
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/Release</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;../../../Framework/Release;..\..\..\..\Allgemein\Network\Network;../../../Network/Release;..\..\..\..\Allgemein\sql\sql;../../../sql/Release;$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <ItemGroup>
+    <ClCompile Include="Datenbank.cpp" />
+    <ClCompile Include="main.cpp" />
+    <ClCompile Include="RegisterServer.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Datenbank.h" />
+    <ClInclude Include="RegisterServer.h" />
+  </ItemGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Link>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/Debug/bin/x64/debug;$(RemoteRootDir)/Network/Debug/bin/x64/debug;$(RemoteRootDir)/Framework/Debug/bin/x64/debug;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <LibraryDependencies>dbgFramework;dbgNetwork;dbgSQL;pq;pthread</LibraryDependencies>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Link>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/Release/bin/x64/release;$(RemoteRootDir)/Network/Release/bin/x64/release;$(RemoteRootDir)/Framework/Release/bin/x64/release;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <LibraryDependencies>Framework;Network;SQL;pq;pthread</LibraryDependencies>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>

+ 30 - 0
RegisterServer/RegisterServer.vcxproj.filters

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{635321ad-ebc6-4b41-9563-9a1848a02307}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headerdateien">
+      <UniqueIdentifier>{5370eb9c-25cd-4efa-846d-939ce62ff0d8}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Datenbank.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="RegisterServer.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Datenbank.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="main.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="RegisterServer.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 54 - 0
RegisterServer/main.cpp

@@ -0,0 +1,54 @@
+#include "RegisterServer.h"
+#include <Zeit.h>
+#include <iostream>
+#include <fstream>
+#include <Globals.h>
+
+int main()
+{
+    Framework::initFramework();
+	Zeit *z = getZeit();
+	Text *pfad = new Text( "../log/register/" );
+	pfad->append( z->getZeit( "y-m-d h-i-s.log" ) );
+	z->release();
+	DateiPfadErstellen( pfad->getThis() );
+	std::ofstream file;
+	file.open( pfad->getText() );
+	std::streambuf* sbuf = std::cout.rdbuf();
+	std::cout.rdbuf( file.rdbuf() );
+	pfad->release();
+
+	std::cout << "RS: Startet...\n";
+	std::cout << "RS: Lese init Datei ../data/rsInit.ini ...\n";
+	InitDatei *dat = new InitDatei( "../data/rsInit.ini" );
+	if( !dat->laden() )
+	{
+		std::cout << "RS: error: Datei konnte nicht gelesen werden. Das Programm wird geschlossen.\n";
+		dat->release();
+		exit( 1 );
+	}
+    const char *wichtig[] = { "ServerId", "DBBenutzer", "DBPasswort", "DBName", "DBIP", "DBPort", "Aktiv", "Java", "Mailer" };
+    for( const char *w : wichtig )
+    {
+        if( !dat->wertExistiert( w ) )
+        {
+            std::cout << "RS: error: Der Wert '" << w << "' wurde nicht gefunden. Das Programm wird geschlossen.\n";
+            dat->release();
+            exit( 1 );
+        }
+    }
+
+	RegisterServer *rserver = new RegisterServer( dat );
+
+	std::cout << "RS: Der Admin Server läuft. Startforgang beendet.\n";
+	rserver->runn();
+
+	rserver->ende();
+	rserver->release();
+	dat->release();
+	std::cout << "RS: Der Server ist heruntergefahren.\n";
+	file.close();
+	std::cout.rdbuf( sbuf );
+    Framework::releaseFramework();
+	return 0;
+}

BIN
RegisterServer/readme/images/ArchOptions.gif


BIN
RegisterServer/readme/images/ChangeRemote.gif


BIN
RegisterServer/readme/images/ManageConnections.gif


BIN
RegisterServer/readme/images/OutputTypes.gif


BIN
RegisterServer/readme/images/debuggerexport.png


BIN
RegisterServer/readme/images/firstconnection.png


BIN
RegisterServer/readme/images/linker.png


BIN
RegisterServer/readme/images/postbuild.png


+ 85 - 0
RegisterServer/readme/readme.html

@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset='utf-8'>
+
+    <link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
+
+    <title>Getting Started</title>
+  </head>
+
+<body>
+
+    <div class="container">
+        <div id="header">
+            <h1>Getting Started</h1>
+            <h2>Visual C++ for Linux Development extension</h2>
+        </div>
+    
+    <table>
+    <tr>    
+    <div id="main_content">
+        
+        <td>
+        <div id="lpanel">
+            <h1>Setting up your project for Linux Development</h1>
+
+            <p>With this extension you can author C++ code for Linux servers, desktops and devices. You can manage your connections to these machines from within VS. VS will automatically copy and remote build your sources and can launch your application with the debugger. Our project system supports targeting specific architectures, including ARM.</p>
+            <img src="images\ArchOptions.gif"/>
+            
+            <h1>Connecting to Linux</h1>
+            <h2>Prerequisites</h2>
+            <p>Today we only support building remotely on the Linux target machine. We are not limited by specific Linux distros but we do have dependencies on the presence of some tools. Specifically, we need openssh-server, g++, gdb and gdbserver. Use your favorite package manager to install them, e.g. on Debian based systems: sudo apt-get install openssh-server g++ gdb gdbserver</p>
+            
+            <h2>First connection</h2>
+            <p>The first time you target a Linux machine you will be prompted for connection information.  This is triggered by building the project.</p>
+            <img src="images\firstconnection.png"/>
+                
+            <h2>Adding and removing connections</h2>
+            <p>To add a new connection, go to Tools > Options and search for Linux. From here you can add and remove connections.</p>
+            <img src="images\ManageConnections.gif"/>
+            
+            <p>To change which connection a project is using go to the project properties remote settings and update the target machine.</p>
+            <img src="images\ChangeRemote.gif"/>
+            
+            <h1>Project Properties</h1>
+            <p>All of the options necessary to control C++ compilation are exposed on the project properies pages. We'll cover a few specific to how things work for Linux. First under remote settings, you will see the remote root is set to ~/projects/ by default and that we are setting the remote project directory to match our project name in that location. </p>
+            <img src="images\OutputTypes.gif"/>
+            
+            <p>Looking at the General settings for the project, you can see how our output and intermediate directories were configured. Additionally, you’ll see that this project was configured as an application – thus our executable is under bin/x64/Debug/ as ConsoleApplication1.out. Notice that for configuration types we also support static and dynamic libraries.</p>
+            
+            <p>Add additional library dependencies on the Linker > Input property page.</p>
+            <img src="images\linker.png"/>
+            
+            <p>You can pass additional pre launch commands to the debugger to do things like launch graphical apps on the remote linux machine.</p>
+            <img src="images\debuggerexport.png"/>
+            
+            <p>You can also send post build events to control remote behavior, as in this example that exports a gpio pin for use without requiring the executable run as super user.</p>
+            <img src="images\postbuild.png"/>
+            
+        </div>
+        </td>
+        <td>
+        <div id="rpanel">
+
+            <h1>Resources</h1>
+
+            <p>Check out the <a href="http://aka.ms/vslinuxext">VS Gallery VC++ for Linux Development page</a> where we will keep updates posted. You can also check out our <a href="https://blogs.msdn.microsoft.com/vcblog/2016/03/30/visual-c-for-linux-development">announcment blog post</a> for more in depth details on configuring the project properties.</p>
+            
+            <p>Here are other utilities you will find useful in connection with this extension.</p>
+            <ul>
+                <li>Learn more about <a href="http://aka.ms/vsiot">IoT Development</a></li>
+                <li><a href="http://aka.ms/vsiotext">VC++ for IoT Development Tools</a></li>
+                <li><a href="https://github.com/Azure/azure-iot-sdks">Azure IoT SDK</a>, includes a C API for connecting small devices to the Azure IoT Hub</li>
+            </ul>
+
+            <h1>Give us feedback</h1>
+            <p><a href="http://aka.ms/vslinux-feedback">UserVoice</a></p>
+        </div>
+        </td>   
+    </div>
+    </tr>
+    </table>
+    </div>
+</body>
+</html>

+ 119 - 0
RegisterServer/readme/stylesheet.css

@@ -0,0 +1,119 @@
+body {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  color: #1E1E1E;
+  font-size: 13px;
+  font-family: "Segoe UI", Helvetica, Arial, sans-serif;
+  line-height: 1.45;
+  word-wrap: break-word;
+}
+
+/* General & 'Reset' Stuff */
+
+
+.container {
+  width: 1100px;
+  margin: 0 auto;
+}
+
+section {
+  display: block;
+  margin: 0;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  margin: 0;
+}
+
+table, tr {
+    width: 1100px;
+    padding: 0px;
+    vertical-align: top;
+  }
+
+/* Header, <header>
+   header   - container
+   h1       - project name
+   h2       - project description
+*/
+
+#header {
+  color: #FFF;
+  background: #68217a;
+  position:relative;
+}
+h1, h2 {
+  font-family: "Segoe UI Light", "Segoe UI", Helvetica, Arial, sans-serif;
+  line-height: 1;
+  margin: 0 18px;;
+  padding: 0;
+}
+#header h1 {
+  font-size: 3.4em;
+  padding-top: 18px;
+  font-weight: normal;
+  margin-left: 15px;
+}
+
+#header h2 {
+  font-size: 1.5em;
+  margin-top: 10px;
+  padding-bottom: 18px;
+  font-weight: normal;
+}
+
+#main_content {
+  width: 100%;
+  display: flex;
+  flex-direction: row;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+  font-weight: bolder;
+}
+
+#main_content h1 {
+  font-size: 1.8em;
+  margin-top: 34px;
+}
+
+    #main_content h1:first-child {
+        margin-top: 30px;
+    }
+
+#main_content h2 {
+  font-size: 1.8em;
+}
+p, ul {
+    margin: 11px 18px;
+}
+
+#main_content a {
+    color: #06C;
+    text-decoration: none;
+}
+ul {
+        margin-top: 13px;
+    margin-left: 18px;
+    padding-left: 0;
+}
+    ul li {
+        margin-left: 18px;
+        padding-left: 0;
+    }
+#lpanel {
+    width: 870px;
+    float: left;
+}
+#rpanel ul {
+    list-style-type: none;
+}
+    #rpanel ul li {
+        line-height: 1.8em;
+    }
+#rpanel {
+    background: #e7e7e7;
+    width: 230px;
+}

+ 2 - 0
build.bat

@@ -0,0 +1,2 @@
+"D:\Visual Studio 2017\MSBuild\15.0\Bin\MSBuild.exe" "Register Server.sln" /t:rebuild /p:configuration=debug /p:platform=x64
+"D:\Visual Studio 2017\MSBuild\15.0\Bin\MSBuild.exe" "Register Server.sln" /t:rebuild /p:configuration=release /p:platform=x64