\chapter{Server}
\section{Python}
\begin{quotation}\begin{flushright}{\it
Python is a truly wonderful language.\\
When somebody comes up with a good idea\\
it takes about 1 minute and five lines\\
to program something \\
that almost does what you want.\\
Then it takes only an hour\\
to extend the script to 300 lines,\\
after which it still does almost what you want.\\
}
Jack Jansen, 1992-07-08
\end{flushright}\end{quotation}

Der Server von ajaxWM wurde und wird komplett in Python geschrieben. Python ist
eine hauptsächlich von Guido van Rossum seit Anfang der 1990er Jahre
entwickelte Scriptsprache. Der Name stellt eine Anlehnung an Monty Python dar.

Der Slogan von Python beschreibt bereits einen der größten Vorteile gegenüber
viele anderen Sprachen: ``Batteries included"' - Dank einer sehr großen
Standardbibliothek werden Module für verschiedenste Einsatzgebiete direkt
mitgeliefert. Dadurch reduzieren sich die Abhängigkeiten des eigenen, in Python
geschriebenen Programms.

Aufgrund der einfachen Syntax ist es ein Leichtes in Python geschriebene
Programme übersichtlich zu halten.

Die Sprache bietet Duck Typing\footnote{``When I see a bird that walks like a
duck and swims like a duck and quacks like a duck, I call that bird a duck."' -
James Whitcomb Riley}, beziehungsweise verfügt nicht über statische
Typisierung. Der Typ einer Variable wird erst während der Laufzeit aus dem
zugewiesenen Inhalt festgelegt. Dies erleichtert die Programmierung, zerrt
jedoch gleichermaßen an der Performance. Desweiteren stellt dieses Verhalten
eine schwierig aufzuspürende Fehlerquelle dar, weil die Typen der Parameter,
die einer Methode beim Aufruf übergeben werden, nicht festgelegt werden können.
Ändert man nun die Typen der zu übergebenden Parameter, nicht aber den Aufruf,
so wird nicht sofort ein Fehler ausgegeben und man erkennt häufig nicht den
Grund für den erst später auftretenden Fehler. 

\section{Startvorgang}
\begin{quotation}\begin{flushright}{\it 
This story gives a straightforward account of\\
the three Minami sisters' normal, everyday lives.\\
Please have no expectations beyond that.\\
Also, please watch with the lights on\\
and sit three metres from the TV.\\
}
Chiaki Minami from Minami-ke
\end{flushright}\end{quotation}

Damit ajaxWM lauffähig ist, ist lediglich Python\footnote{Getestet mit Python
2.4 und 2.5} nötig. Psyco, ein JIT-Compiler\footnote{JIT steht für Just in
Time} für Python-Code, der optional mit ajaxWM verwendet werden kann,
beschleunigt den Server enorm. Da Linux die Hauptentwicklungsplattform ist,
läuft der ajaxWM-Server darauf relativ stabil. Jedes andere Betriebssystem,
unter dem Python lauffähig ist und das Threading und PTTYs
unterstützt\footnote{*BSD, Cygwin unter Windows, \ldots}, sollte auch ohne
beziehungsweise mit geringem Arbeitsaufwand nutzbar sein.

Beim Ausführen des Server-Programms, das im Normalfall als {\tt ajaxwm.py} zur
Verfügung steht, hat man eine Auswahl an übergebbaren POSIX-konformen
Parametern zu treffen. Ein {\tt -h} dient zur Anzeige des folgenden Hilfetexts:

\lstset{language=Sh} 
\begin{lstlisting}[caption=Hilfetext]{hilfetext}
r0q@kana /home/r0q $ ./ajaxwm.py
usage: ajaxwm.py [options]

options:
  -h, --help            show this help message and exit
  -d, --daemon          run in background
  -p PORT, --port=PORT  set the TCP port (default: 8022)
  -l, --log             log requests to stderr (default: quiet mode)
  -P PIDFILE, --pidfile=PIDFILE
                        set the pidfile (default: /var/run/ajaxwm.pid)
  -U UID, --uid=UID     set the user id
  -u, --uncompressed    responds not compressed (lower system load, higher
                        network load)
  -s SSHCMD, --sshcmd=SSHCMD
                        ssh client to use
r0q@kana /home/r0q $ 
\end{lstlisting}

Das ganze auf Deutsch:

{\tt -h} oder {\tt {-}{-}help}: Hilfetext anzeigen\\
{\tt -d} oder {\tt {-}{-}daemon}: Im Hintergrund laufen: Der Server läuft, man kann jedoch im
Terminal weiterarbeiten.\\
{\tt -p PORT} oder {\tt {-}{-}port=PORT}: Den Port, auf dem der Socket lauscht, festlegen.
Standardwert ist 8022.\\
{\tt -l} oder {\tt {-}{-}log}: Anfragen auf der Standardfehlerausgabe ausgeben.\footnote{Im
Normalfall stellt der Monitor die Standardfehlerausgabe dar. Mit {\tt ./ajaxwm
-l 2> anfragen.txt} kann man sie beispielsweise auf die Datei {\tt
anfragen.txt} umleiten.} Andernfalls werden Anfragen nicht geloggt.\\
{\tt -P PIDFILE} oder {\tt {-}{-}pidfile=PIDFILE}: Die Datei, in der die Process-ID des
Programms geschrieben werden soll. Diese PID ist dazu notwendig dem Programm, wenn
es bereits läuft, Signale, wie einen SIGTERM\footnote{Der Begriff SIGTERM kommt
von SIG für Signal und TERM für Terminieren und beendet den Programmprozess.},
zu senden.\\
{\tt -U UID} oder {\tt {-}{-}uid=UID}: Festlegen des Users, als der das
Programm laufen soll, mittels der User-ID. Nur möglich, sofern es als root
ausgeführt wurde. Dadurch gibt das Programm seine Rechte ab und die Nutzung ist
sicherer, da eine Sicherheitslücke im Programm nur die Dateien des aktuellen
Users gefährdet, nicht wie sonst das gesamte System. Standardmäßig behält das
Programm die UID, unter der es ausgeführt wurde.\\
\hypertarget{uncompressed}{{\tt -u} oder {\tt {-}{-}uncompressed}:} Im Normalfall werden die
Antworten auf Anfragen mit gzip komprimiert. Hierdurch kann dieses Verhalten
deaktiviert werden, was insbesondere in lokalen Netzwerken von Vorteil ist.
Unkomprimierte Antworten benötigen nämlich weniger Rechenleistung, dafür steigt
die Netzwerklast.\\
{\tt -s SSHCMD} oder {\tt {-}{-}sshcmd=SSHCMD}: Auszuführender SSH Clients, im Normalfall {\tt
ssh}.\\

Eine Manpage\footnote{Als Manpage (Manual Page) bezeichnet man die in unixoiden
Betriebssystemen eingesetzen Hilfeseiten.} wurde noch nicht geschrieben, ist
jedoch für die Zukunft geplant.

Beim Starten im Vordergrund (nicht als Daemon) wird nur die Adresse ausgegeben,
auf die man im Webbrowser zugreifen kann. Beim Starten im Hintergrund wird
zusätzlich noch die Process-ID ausgegeben, damit man den Prozess wieder beenden
kann.\footnote{Weitere Informationen über das Beenden des Servers unter
\hyperlink{beenden_des_programms}{Beenden des Programms}.} Ist der Port, der
verwendet werden soll, bereits belegt, so wird dies ausgegeben und der Server
beendet.

\lstset{language=Sh}
\begin{lstlisting}[caption=Testlauf]{testlauf}
r0q@kana /home/r0q $ ./ajaxwm.py -d
http://localhost:8022/ PID: 6910
r0q@kana /home/r0q $ ./ajaxwm.py
http://localhost:8022/
port 8022 already in use
r0q@kana /home/r0q $ kill 6910
r0q@kana /home/r0q $ ./ajaxwm.py
http://localhost:8022/
\end{lstlisting}

Wenn der Server gestartet wird, werden lediglich zwei Hauptaufgaben erledigt,
bevor er in einen passiven Zustand fällt und auf den Verbindungsaufbau von
Seiten eines Clients wartet: einen Socket öffnen und auf Anfragen lauschen und
die Dateien, die Clients zur Verfügung gestellt werden sollen, in den
Arbeitsspeicher laden und dabei selektieren und eventuell die Inhalte der
Dateien verändern.

\subsection{Socket öffnen und lauschen}
AjaxWM verwendet das von Anthony Lesuisse\footnote{Anthony Lesuisse ist ~--
nebenbei erwähnt ~-- auch der Autor von AjaxTerm.} stammende QWeb-Framework. Es
stellt einen WSGI\footnote{Web Server Gateway Interface}-Server zur Verfügung.
Möglicherweise wird das Framework jedoch in nächster Zeit durch ein anderes
ersetzt. Performance-Tests sind zur Auffindung eines geeigneteren Frameworks
geplant.

Der WSGI-Server sorgt dafür, dass alle gültigen Anfragen, die am geöffneten
Socket eingehen, an die Server-Klasse weitergeleitet werden. Diese Klasse hat
dann die Aufgabe eine Antwort zu generieren, dazu aber später unter \hyperlink{beantworten_von_anfragen}{Beantworten von Anfragen} mehr.

\hypertarget{dateien_selektieren_und_laden}{\subsection{Dateien selektieren und laden}}
Die Files-Klasse ist für das Auswählen und Laden der Dateien zuständig. Sie
wird später durch ein File-Modul ersetzt werden, das weitaus mehr Fähigkeiten
bieten wird. Bisher werden lediglich rekursiv alle Dateien im Ordner {\it
htdocs} und alle Themes, die mit der verwendeten Version von ajaxWM kompatibel
sind, zur Verfügung gestellt. Letzteres funktioniert dadurch, dass die Themes,
die im Ordner \hyperlink{themes}{themes} liegen, in weitere Ordner mit den
Versionsnummern unterteilt werden. Beispielsweise der Ordner des Themes
\hyperlink{lim}{lim} (less is more) liegt unter {\it themes}/{\it 0.2.0}.
Der Server weiß, dass der von ihm zur Verfügung gestellte Client mit allen
Themes, deren Versionsnummer zwischen 0.1.0 und 0.3.0 liegt, lauffähig ist und
lädt lim. Würde sich aber in Version 0.4.0 der Aufbau von Themes ändern, so
wird ein zu dieser Version gehörender Theme nicht geladen, da er nicht zwischen
0.1.0 und 0.3.0 liegt. Beim Laden wird weiterhin eine Datei {\it themes.xml}
on-the-fly im Arbeitsspeicher erstellt. Dadurch kann der Client herausfinden,
welche Themes ihm zur Verfügung gestellt werden und dem User eine
Auswahlmöglichkeit bieten. Die Datei sieht dann beispielsweise so aus:
\lstset{language=XML}
\begin{lstlisting}[caption=Verfügbare Themes]{themes}
<?xml version="1.0" ?>
<ajaxwm>
    <theme author="Andreas Waidler" email="andreaswaidler@arcor.de" name="lim">
        <path>
            /themes/lim/lim.xml
        </path>
        <description>
            Less Is More. Extremly minimalistic theme.
        </description>
    </theme>
    <theme author="Anderer Autor" email="irgendeine.email@adres.se" name="bla">
        <path>
            /themes/bla/bla.xml
        </path>
        <description>
            Ein Beispieltheme.
        </description>
    </theme>
</ajaxwm>
\end{lstlisting}

Das File-Modul wird zusätzlich über eine Kompressionsfunktion verfügen. Dabei
können wahlweise JavaScript-Dateien platzsparender übertragen werden, indem
Kommentare und nutzlose Zeilen entfernt werden. Möglich ist auch, alle
JavaScript-Dateien in einer zusammenzufassen, wodurch ein enormer
Geschwindigkeitsschub beim Initialisieren des Clients erreicht werden würde, da
die Übertragung von vielen einzelnen, kleinen Dateien stets mehr Zeit in
Anspruch nimmt als die Übertragung einer großen Datei. Um nicht bei jedem
Neustarten der Serveranwendung die Kompressionsalgorithmen wiederholen zu
müssen, werden die komprimierten Dateien gespeichert werden. Bei einem erneuten
Starten mit aktivierter Kompression kann überprüft werden, ob sich die
unkomprimierten JavaScript-Dateien seit der letzten Kompression verändert
haben. Ist dies nicht der Fall, entfällt eine erneute Kompression. 

Diese Kompressionsmethoden haben jedoch einen entscheidenden Nachteil, weshalb
sie unbedingt optional angeboten werden müssen: Auf Seiten des Clients kommt
ein für Menschen schwer lesbarer und unkommentierter Code an. Dies erschwert
die Fehlersuche.

Eine weitere Funktion, die das Debuggen des JavaScript-Codes erleichtern wird,
werden die DEBUG-Blöcke, die im JavaScript-Code in Form von speziellen
Kommentaren angegeben werden können und vom File-Modul dann, entsprechend dem
gewählten Parameter, im Code beibehalten bleiben oder entfernt werden. Somit
ist eine Abwägung zwischen Performance (normaler Betrieb) und erweitertem
Debugging (Testbetrieb) möglich.

\section{Sichere Verbindung}
\begin{quotation}\begin{flushright}{\it 
Ich glaube, die meisten Menschen\\
wissen gar nicht was ein Rootkit ist,\\
warum sollen sie sich also darum kümmern?\\
}
Thomas Hesse, Präsident Global Digital\\
Business-Abteilung bei Sony BMG
\end{flushright}\end{quotation}

Standardmäßig lässt sich ajaxWM nur lokal nutzen. Dieses Verhalten ist
beabsichtigt, da der Server über keine eigene Verschlüsselung bei der
Kommunikation verfügt. Um ajaxWM nach außen hin anzubieten, ist es nötig einen
lokalen Proxy laufen zu lassen. In diesem Fall den Apache WebServer, der eine
Proxy-Weiterleitung mit HTTPS bietet. HTTPS ist mit jedem aktuellen Browser
nutzbar und verwendet SSL/TLS zur Verschlüsselung. Dadurch ist, im Gegensatz zu
HTTP, asynchronen Schlüsseln sei Dank, ein Mitlesen der Kommunikation im
Klartext durch alle Stationen, die zwischen Client und Server liegen, nicht
möglich.

\subsection{Apache-Konfiguration}
Eine VHost-Konfigurationsdatei für Apache kann wie folgt aussehen:
\lstset{language=Sh}
\begin{lstlisting}[caption=/etc/apache2/vhosts.d/ajaxwm.conf]{vhosts}
Listen 443
NameVirtualHost *:443

<VirtualHost *:443>
   ServerName localhost
   SSLEngine On
   SSLCertificateKeyFile ssl/apache.pem
   SSLCertificateFile ssl/apache.pem

   ProxyRequests Off
   <Proxy *>
           AuthType Basic
           AuthName "ajaxWM access"
           AuthUserFile /etc/apache2/htpasswd
           Require user r0q
           Order deny,allow
           Allow from all
   </Proxy>
   ProxyPass /ajaxwm/ http://localhost:8022/
   ProxyPassReverse /ajaxwm/ http://localhost:8022/
</VirtualHost>
\end{lstlisting}

\section{Beantworten von Anfragen}\hypertarget{beantworten_von_anfragen}{}
\begin{quotation}\begin{flushright}{\it 
{\it Konata}: Skills you learn from playing \\
video games have no use later in life.\\
{\it Kagami}: You're living proof of that.\\
}
Lucky Star
\end{flushright}\end{quotation}

Sowohl der Inhalt eines Terminals in Form einer XML-Datei als auch reguläre
Dateien werden, sofern nicht per \hyperlink{uncompressed}{Parameter}
deaktiviert, mit gzip komprimiert übertragen.

Die Bedeutungen der jeweiligen Antworten sind dem Kapitel
\hyperlink{kommunikationsprotokoll}{Kommunikationsprotokoll} zu entnehmen.

\subsection{Zur Verfügung Stellen von Dateien}
Wie bereits unter \hyperlink{dateien_selektieren_und_laden}{Dateien selektieren
und laden} beschrieben, werden die Dateien in den Arbeitsspeicher geladen. Das
{\it htdocs}-Verzeichnis dient als root, was bedeutet, dass die Datei {\it
htdocs/index.html} als {\it /index.html} verfügbar gemacht wird. Intern werden
die Dateien in einem Wörterbuch (assoziatives Array) gespeichert. Wird versucht
auf nicht vorhandene Dateien zuzugreifen, wird der HTTP-Statuscode 404 (Not
Found) zurückgegeben. 

\subsection{Login}
Bei einer Login-Anfrage werden der übergebene Benutzername und das Passwort auf
Gültigkeit überprüft. Der Benutzername muss dem Muster eines UNIX-Usernames
entsprechen, darf also nur aus alphanumerischen Zeichen, Unterstrichen,
Punkten, und Dollarzeichen bestehen. Beim Passwort wird lediglich geprüft, ob
kein leerer String übergeben wurde.

Anschließend wird eine zufällige, noch nicht belegte, Session-ID generiert und
die Korrektheit von Benutzername und Passwort durch einen Login-Versuch
sichergestellt. Das Festlegen des Zielrechners ist noch nicht möglich, da der
Client keine derartige Information überträgt.

Es wird nicht nur eine Session erstellt, sondern auch eine Instanz der
Loop-Klasse. Diese überprüft, ob innerhalb der letzten 10 Minuten kein Zugriff
auf die soeben erstellte Session mehr hergestellt wurde. Dies würde bedeuten,
dass die Verbindung zum Client unterbrochen wurde und dieser sie nicht wieder
aufbauen konnte. In diesem Fall wird die Session beendet.

\subsection{Logout}
Der Logout ist das Gegenstück zum Login. Er beendet die angegebene Session,
sofern sie existiert. Da dies zur Zeit für jeden möglich ist, ist es wichtig,
dass beim Login eine zufällige Session-ID zwischen 0 und der maximalen Größe
eines Integers auf dem jeweiligen System\footnote{Auf einem x86-PC ist dies
$2147483647$, also $2^{31}-1$.} zugewiesen wird.

\subsection{Fenster erzeugen}
Um die Performance zu erhöhen, wird die Fenster-ID wird immer um eins
hochgezählt bis sie 64 erreicht hat, auch wenn vorige Fenster bereits beendet
wurden. Sind bereits 64 Fenster erstellt worden, wird stattdessen nach nicht
mehr geöffneten Fenstern gesucht und das erste gefundene neu initialisiert.

\subsection{Fenster schließen}
Das Schließen von Fenstern ist das Gegenstück zum Erzeugen. Das im Fenster
laufende Programm wird lediglich gebeten, nicht gezwungen, sich zu beenden.

\subsection{Fenster zerstören}
Das Zerstören von Fenstern ist noch nicht integriert. Es wird vermutlich mit
SIGKILL arbeiten, während das Schließen des Fensters ein SIGTERM bewirkt.

\subsection{Synchronisation und Tastendruck}
Diese beiden, nahezu identischen Events erreichen den Server am häufigsten.
Eine Synchronisation ermöglicht es die Größe eines Fensters zu verändern. Dabei
wir dem Fenster, der dem Fenster zugehörigen Instanz der Terminal-Klasse, und
dem Terminal selbst die Veränderung mitgeteilt.

Durch das Tastendruck-Event werden die übermittelten Tasten in das Terminal
geschrieben. Anschließend wird für einen kurzen Zeitraum gewartet, damit das
im Terminal laufende Programm diese verarbeiten kann. Dieser Zeitraum ist so
gewählt, dass er einer Shell die Verarbeitung erlaubt.

Bei beiden Events wird jetzt der Inhalt des Terminals erneut ausgelesen und die
Terminal-Klasse generiert das zurückzugebende XML-Dokument. Ist dieses jedoch
identisch mit dem letzten übertragenem, so wird mit einem {\it idem}
signalisiert, dass das Terminal sich nicht verändert hat.

\lstset{language=XML}
\begin{lstlisting}[caption=Rückgabe bei verändertem Inhalt, breaklines=true]{xml}
<?xml version="1.0" encoding="UTF-8"?><pre class="term"><span class="f11 b0"> 1 </span><span class="f7 b1"> </span><span class="f7 b0">
         
</span><span class="f12 b0">~                                                                       
        
~                                                                               
~                                                                               
~                                                                               
~                              </span><span class="f7 b0">VIM - Vi IMproved</span><span class="f12 b0">
~                                                                               
~                               </span><span class="f7 b0">version 7.1.123</span><span class="f12 b0">
~                           </span><span class="f7 b0">by Bram Moolenaar et al.</span><span class="f12 b0">
~                          </span><span class="f7 b0">Modified by Gentoo-7.1.123</span><span class="f12 b0">
~                 </span><span class="f7 b0">Vim is open source and freely distributable</span><span class="f12 b0">
~                                                                               
~                        </span><span class="f7 b0">Become a registered Vim user!</span><span class="f12 b0">
~                </span><span class="f7 b0">type  :help register</span><span class="f12 b0">&lt;Enter&gt;</span><span class="f7 b0">   for information </span><span class="f12 b0">
~                                                                               
~                </span><span class="f7 b0">type  :q</span><span class="f12 b0">&lt;Enter&gt;</span><span class="f7 b0">               to exit         </span><span class="f12 b0">
~                </span><span class="f7 b0">type  :help</span><span class="f12 b0">&lt;Enter&gt;</span><span class="f7 b0">  or  </span><span class="f12 b0">&lt;F1&gt;</span><span class="f7 b0">  for on-line help</span><span class="f12 b0">
~                </span><span class="f7 b0">type  :help version7</span><span class="f12 b0">&lt;Enter&gt;</span><span class="f7 b0">   for version info</span><span class="f12 b0">
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
</span><span class="f7 b0">                                                              0,0-1         All
</span></pre>
\end{lstlisting}

\begin{center}
\includegraphics[width=0.85\textwidth]{Kapitel3/ausgabe.png}
\end{center}

\lstset{language=XML}
\begin{lstlisting}[caption=Rückgabe bei unverändertem Inhalt, breaklines=true]{xml2}
<?xml version="1.0" encoding="UTF-8"?><idem></idem>
\end{lstlisting}

\section{SSH}
\begin{quotation}\begin{flushright}{\it 
Come the Sun King blade ablur\\
Hammer down eclipse the Sun\\
And Puff, the land secured\\
The new King Barbarian!\\
}
Ty Semaka\\
{\glqq}Puff the Barbarian{\grqq}
\end{flushright}\end{quotation}

Die SSH-Klasse bietet dynamische und erweiterbare Unterstützung für
SSH-Client-Programme. OpenSSH und DropBear sind bereits integriert und sollten
für die meisten Anwender genügen. Die Klasse kann selbstständig erkennen, um
welchen Client es sich handelt und für diesen die Kommandozeilen zum Überprüfen
der Logindaten und zum Einloggen zur Verfügung stellen.

\section{Kommunikation mit Terminals}
\begin{quotation}\begin{flushright}{\it 
Unicode: everyone wants it,\\
until they get it.\\
}
Barry Warsaw, 2000-05-16
\end{flushright}\end{quotation}

Für die Kommunikation mit dem virtuellen Terminal ist die Window-Klasse
zuständig. Der Inhalt des virtuellen Terminals wird in einer Instanz der
Terminal-Klasse gespeichert. Diese Klasse ist besonders aufwändig, da sich in
Terminals nicht nur ausgebbare Zeichen befinden können. ASCII- und
ANSI-Steuersequenzen sind ebenfalls ein wichtiger Bestandteil eines jeden
Terminals.

\begin{longtable}{p{0.2\textwidth}|p{0.7\textwidth}}
{\it Wert} & {\it Aktion}\\
\hline
{\tt 0x08} & Bewegt den Cursor um eine Position nach links. Falls sich der Cursor
bereits am Zeilenanfang befindet, bleibt dieses Steuerzeichen wirkungslos. \\
{\tt 0x09} & Positioniert den Cursor auf die nächste Tabulatormarke oder an den
rechten Bildschirmrand, falls keine weiteren Tabulatormarken vorhanden sind. \\
{\tt 0x0A} & Setzt den Cursor an den Anfang der nächsten Zeile. \\
{\tt 0x0D} & Verschiebt den Cursor an den Anfang der aktuellen Zeile.\\
\caption{Unterstützte ASCII-Steuersequenzen}
\end{longtable}

\begin{longtable}{p{0.2\textwidth}|p{0.7\textwidth}}
{\it Wert} & {\it Aktion} \\
\hline
{\tt CSI n A}       & Bewegt den Cursor um n (Standardwert 1) Zeilen nach oben. \\
{\tt CSI n B}       & Bewegt den Cursor um n (Standardwert 1) Zeilen nach unten. \\
{\tt CSI n C}       & Bewegt den Cursor um n (Standardwert 1) Spalten nach rechts. \\
{\tt CSI n D}       & Bewegt den Cursor um n (Standardwert 1) Spalten nach links. \\
{\tt CSI n E}       & Bewegt den Cursor an den Anfang der um n (Standardwert 1)
Zeilen weiter unten liegenden Zeile. \\
{\tt CSI n F}       & Bewegt den Cursor an den Anfang der um n (Standardwert 1)
Zeilen weiter oben liegenden Zeile. \\
{\tt CSI n G}       & Bewegt den Cursor zu Zeile n. \\
{\tt CSI n H}       & Bewegt den Cursor zu Zeile n, Spalte m (Standardwerte 1). \\
{\tt CSI n J}       & Leert einen Teil des Terminals. Wenn n null ist (oder fehlt),
wird vom Cursor aus bis zum Ende des Terminals geleert. Wenn n eins ist, wird
vom Cursor aus bis zum Anfang des Terminals geleert. Wenn n zwei ist, wird das
gesamte Terminal geleert. \\
{\tt CSI n K}       & Leert einen Teil der Zeile. Wenn n null ist (oder fehlt), wird
vom Cursor aus bis zum Ende der Zeile geleert. Wenn n eins ist, wird vom Cursor
aus bis zum Anfang der Zeile geleert. Wenn n zwei ist, wird die gesamte Zeile
geleert. Die Cursorposition bleibt unverändert. \\
{\tt CSI n n;m f}   & Das selbe wie {\tt CSI n H}. \\
{\tt CSI n n[;m] m} & Setzt den SGR (Select Graphic Rendition) Parameter. Nach {\tt
CSI} können null oder mehr Parameter durch {\it ;} getrennt, folgen. Ohne
Parameter wird {\tt CSI m} wie {\tt CSI 0 m} (reset / normal) behandelt, was
für die meisten ANSI-Steuersequenzen typisch ist. \\
{\tt CSI s}         & Speichert die Position des Cursors. \\
{\tt CSI u}         & Stellt die Position des Cursors wieder her. \\
{\tt CSI ?25l}      & Macht den Cursor unsichtbar. \\
{\tt CSI ?25h}      & Macht den Cursor sichtbar. \\
\caption{Auszug aus unterstützten ANSI-Steuersequenzen}
\end{longtable}

\begin{longtable}{l|p{0.6\textwidth}}
{\it Code} & {\it Effekt} \\
\hline
{\tt 0, 27, 39, 49} & Reset / Normal (Alle Attribute zurücksetzen) \\
{\tt 1}             & Fettschrift \\ 	
{\tt 7}             & Hintergrund- und Vordergrundfarben vertauschen \\
{\tt
\colorbox{0}{\textcolor{7}{30}}\colorbox{1}{\textcolor{0}{31}}\colorbox{2}{\textcolor{0}{32}}\colorbox{3}{\textcolor{0}{33}}\colorbox{4}{\textcolor{0}{34}}\colorbox{5}{\textcolor{0}{35}}\colorbox{6}{\textcolor{0}{36}}\colorbox{7}{\textcolor{0}{37}}}
& Vordergrundfarbe setzen \\
{\tt
\colorbox{0}{\textcolor{7}{40}}\colorbox{1}{\textcolor{0}{41}}\colorbox{2}{\textcolor{0}{42}}\colorbox{3}{\textcolor{0}{43}}\colorbox{4}{\textcolor{0}{44}}\colorbox{5}{\textcolor{0}{45}}\colorbox{6}{\textcolor{0}{46}}\colorbox{7}{\textcolor{0}{47}}}
& Hintergrundfarbe setzen \\
\caption{Unterstützte SGR-Parameter}
\end{longtable}

Die Terminal-Klasse speichert die Zeichen (in Unicode), die Vorder-, die Hintergrundfarben,
und die Cursorposition und kann diese auf Abruf zurückgeben.

\section{Beenden des Programms}\hypertarget{beenden_des_programms}{}
\begin{quotation}\begin{flushright}{\it 
I have to stop now.\\
I've already told you more than I know.\\
}
Wolf Logan, 1999-01-14
\end{flushright}\end{quotation}

Bei einem Keyboard-Interrupt ~-- in den meisten Betriebssystem durch {\tt STRG +
C} hervorzurufen ~-- wird der Server beendet. Hat man ihn jedoch als Daemon
gestartet, ist dies nicht möglich. Es gibt mehrere Möglichkeiten den
Hintergrundprozess zu beenden: Es wird beim Starten als Daemon auch die PID
ausgegeben. Lautet diese beispielsweise {\it 1234}, lässt sich ajaxWM mit einem
{\tt kill 1234} beenden. Hat man die PID nicht mehr zur Verfügung, lässt sich
diese so herausfinden:
\lstset{language=Sh}
\begin{lstlisting}[caption=Instanz beenden]{beenden}
r0q@kana /home/r0q $ ps -ef | grep python | grep ajaxwm.py | grep -v grep | \
                     tr -s ' ' | cut -d' ' -f2,8-
9640 python src/ajaxwm.py -d
9685 python src/ajaxwm.py -d -p 8023
r0q@kana /home/r0q $ kill 9640
r0q@kana /home/r0q $ ps -ef | grep python | grep ajaxwm.py | grep -v grep | \
                     tr -s ' ' | cut -d' ' -f2,8-
9685 python src/ajaxwm.py -d -p 8023
r0q@kana /home/r0q $ 
\end{lstlisting}
Eine kurze Erklärung der Befehlszeile\footnote{Die Befehlsanreihung ist aus
ästhetischen Gründen in zwei Zeilen unterteilt.}: Das {\tt ps -ef} liefert eine
Liste mit allen laufenden Prozessen und Informationen zu diesen. Durch eine
Pipe ({\tt |}) erhält {\tt grep} dessen Ausgabe und behält nur die Zeilen bei,
die das Wort {\it python} enthalten, also alle Prozesse, die zu
Python-Programmen gehören. Anschließend wird nach
\hyperlink{ajaxwm.py}{ajaxwm.py} gefiltert und {\it grep} von der Liste durch
ein {\tt -v} ausgeschlossen. Jetzt befinden sich zwischen den Informationen zu
jedem Prozess mehrere Leerzeichen, die mit einem {\tt tr -s ' '} durch ein
einzelnes ersetzt werden. {\tt cut} unterteilt nun mit {\tt -d' '} nach diesen
Leerzeichen in Blöcke und gibt dabei Block zwei, die PID, und alles ab Block
acht, also das Programm und die Parameter, mit denen es ausgeführt wurde, aus.

Wir können sehen, dass bereits zwei Instanzen von ajaxWM im Hintergrund ({\tt
-d}) laufen. Die eine auf dem Port 8022 (Standard), die andere auf 8023 ({\tt
-p}). Wie schon zuvor lassen sich nun die Instanzen mit {\tt kill} beenden. Es
ist ebenfalls möglich alle Instanzen von ajaxWM zu beenden:
\lstset{language=Sh}
\begin{lstlisting}[caption=Alle Instanzen beenden]{alle_beenden}
r0q@kana /home/r0q $ ps -ef | grep python | grep ajaxwm.py | grep -v grep | \
                     tr -s ' ' | cut -d' ' -f2,8-
10516 python src/ajaxwm.py -d -p 1234
10529 python src/ajaxwm.py -d -p 1235
10535 python src/ajaxwm.py -d -p 1236
10541 python src/ajaxwm.py -d -p 1237
10547 python src/ajaxwm.py -d -p 1238
r0q@kana /home/r0q $ kill `ps -ef | grep python | grep ajaxwm.py | \
                     grep -v grep | tr -s ' ' | cut -d' ' -f2`
r0q@kana /home/r0q $ ps -ef | grep python | grep ajaxwm.py | grep -v grep | \
                     tr -s ' ' | cut -d' ' -f2,8-
r0q@kana /home/r0q $ 
\end{lstlisting}
Man kann sehen, dass wir im Vergleich zur bisherigen Befehlszeile nich viel
verändert haben. Das {\tt kill} beendet direkt den oder die Prozesse, die in
den {\it `} stehen. Durch das {\tt -f2} gibt {\tt cut} nur die PIDs, nicht aber
den Programmnamen und die Parameter, aus.

Um zu verhindern, dass man die Process-ID nicht weiß und durch obige Methode
herauszufinden hat, kann man beim Start die PID in eine Datei speichern mit
{\tt ./ajaxwm.py -d -P ajaxwm.pid}. Zum beenden dieser Instanz genügt nun ein

{\tt kill `cat ajaxwm.pid`}
