
\chapter{Eisfair Konfigurationsschicht}

\section{Grundlagen der \eisfair\ Konfiguration}

    Das wohl wichtigste Merkmal von \eisfair\ ist die f"ur alle Pakete einheitliche
    Konfiguration. Deshalb ist die Nutzung der \eisfair--Konfigurationsschicht
    eine absolute Voraussetzung f"ur ein \eisfair--Paket.

    Im Folgenden wird der Aufbau einer solchen \eisfair--Konfigurationsdatei
    sowie die damit zusammenh"angenden Mechanismen beschrieben.


\marklabel{configuration}{\section{Speicherung der Konfiguration}}

    Die aktuelle Konfiguration eines Pakets wird immer in der Datei \texttt{/etc/config.d/\package}
    gespeichert. Der Aufbau der Konfigurationsdateien ist weiter unten detailiert beschrieben.

    Diese Datei wird bei einem \eisfair--Paket nicht mitgeliefert, da diese
    bei der Installation eine eventuell bereits vorhandene Konfiguration einer vorher
    installierten Version des Pakets "uberschreiben w"urde. Bei einer Erstinstallation
    muss diese aber erstellt werden. Das kann z.B. durch Kopieren der Standardkonfigurationsdatei
    erfolgen. (Siehe auch Kapitel \jump{install}{Paketinstallation})

    Die Standardkonfigurationsdatei liegt unter \texttt{/etc/default.d/\package}. Diese Datei muss
    in einem \eisfair--Paket mitgeliefert werden. In ihr muss das Paket deaktiviert sein, d.h.
    die Startvariable \texttt{START\_\PACKAGE} \textbf{muss} auf "`no"' gesetzt sein.

    Bei jedem Editieren einer Konfiguration wird mittels ACFH (\jump{acfh}{Advanced Configuration
    File Handling}) eine Sicherheitskopie der letzten Konfiguration unter \texttt{/etc/backup.d/\package}
    erstellt. Die Verwaltung dieser Sicherheitskopien erfolgt mittels der ACFH--Funktionalit"at und
    muss nicht in jedem Paket einzeln implementiert werden.


\subsection{Aufbau einer \eisfair--Kofigurationsdatei}

\begin{example}
Beispiel f"ur eine \eisfair--Konfigurationsdatei (Paket foo):
\begin{verbatim}
# -----------------------------------------------------------------------
# /etc/config.d/foo - foo configuration parameters
#
# Creation:     2005-02-01  max
# Last Update:  2005-03-06  max
#
# Copyright (c) 2001-2014 the eisfair team, team(at)eisfair(dot)org
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# -----------------------------------------------------------------------

# -----------------------------------------------------------------------
# General settings
# -----------------------------------------------------------------------

START_FOO='no'                          # start foo: yes or no

FOO_GENERAL_SETTING='60'                # time for foo
FOO_ANOTHER_SETTING='Test'              # text for foo

FOO_LONG_COMMNET='yes'                  # you can write long comments by
                                        # using more than one line...


# -----------------------------------------------------------------------
# Second Group
#
# You can give a detailed description of this group inside
# the comment
# -----------------------------------------------------------------------

FOO_ARRAY_N='3'                         # number of elements in array

FOO_ARRAY_1_ACTIVE='yes'                # is element active: yes or no
FOO_ARRAY_1_TEXT='Sample'               # some text for an array element
FOO_ARRAY_1_VALUE='12345'               # a number for this element

FOO_ARRAY_2_ACTIVE='no'                 # is element active: yes or no
FOO_ARRAY_2_TEXT='Inactive'             # some text for an array element
FOO_ARRAY_2_VALUE=''                    # a number for this element

FOO_ARRAY_3_ACTIVE='yes'                # is element active: yes or no
FOO_ARRAY_3_TEXT='Something'            # some text for an array element
FOO_ARRAY_3_VALUE='999'                 # a number for this element


# -----------------------------------------------------------------------
# End
# -----------------------------------------------------------------------
\end{verbatim}
\end{example}

    Damit die Konfiguration mittels eines \eisfair--Konfigurationseditors
    bearbeitet werden kann, ist die Struktur der Konfigurationsdatei
    zwingend einzuhalten. Im Folgenden werden die einzelnen Bl"ocke n"aher beschrieben.

    Generell werden spezielle Bl"ocke mittels der Trennzeilen "`\texttt{\#----------}"'
    gekennzeichnet.


\subsection{Kopfbereich und Fussbereich}

    Vor der eigentlichen Konfiguration steht der Kopfbereich, der im Allgemeinen
    der GPL--Header ist und einen Verweis auf die GPL enth"alt, da wohl die meisten
    Pakete unter der GPL stehen werden.

    Am einfachsten sollte der hier angegebene Kopfbereich einfach "ubernommen
    und nur die relevanten Inhalte angepasst werden.

    Als Fussbereich wird das Ende der Datei mit "`\texttt{\# End}"' gekennzeichnet.


\subsection{Gruppenstruktur}

    Die gesamte Konfiguration wird in einzelne Gruppen unterteilt. Jede Gruppe
    wird "uber den Gruppenkopf n"aher beschrieben. Dieser wird mittels einer
    Trennzeile "`\texttt{\#----------}"' eingeleitet und abgeschlossen.

    Dazwischen steht in der ersten Zeile der \textit{Gruppenname} und in den
    Folgezeilen ein \textit{optionaler Kommentar} zur gesamten Gruppe. Dort k"onnen
    n"ahere Angaben zu den in der Gruppe zu konfigurierenden Funktionen gemacht
    werden (aber hier noch ohne Bezug zur einzelnen Konfigurationsvariable).


\subsection{Konfigurationsvariablen}

    Innerhalb der einzelnen Gruppen stehen die Konfigurationsvariablen.
    Unter diesen nimmt die Startvariable \texttt{START\_\PACKAGE} eine
    Sonderstellung ein. Durch diese Variable wird das gesamte Paket
    aktiviert bzw. deaktiviert.

    Alle anderen Variablen haben die Form \texttt{\PACKAGE\_OPTION}, d.h.
    jede der Variablen bekommt als Pr"afix den Paketnamen. Die anderen
    Namensbestandteile werden mittels des Unterstrichs "`\_"' abgetrennt.

    Konfigurationsvariablen werden prinzipiell durchgehend gross geschrieben.

    Jede Konfigurationsvariable kann mit einem eigenen Kommentar n"aher
    beschrieben werden. Dieser Kommentar kann dabei entweder hinter
    der Variable stehen (mittels mindestens eines Leerzeichens plus einem
    Kommentarzeichen "`\#"' abgetrennt) oder in der Folgezeile.
    In diesem Fall muss der Kommentar mittels eines oder mehrerer Leerzeichen
    einger"uckt sein, das Kommentarzeichen darf also \textbf{nicht} in der
    ersten Spalte stehen.

    Mehrzeilige Kommentare sind m"oglich, dabei d"urfen die Kommentarzeichen
    in keiner Zeile in der ersten Spalte stehen.

    Um Optionen anzugeben, die in einer variablen Anzahl auftreten k"onnen,
    m"ussen mehrere Felder verwendet werden. Diese bestehen aus einer Variable,
    die die Anzahl der Werte angibt (\texttt{FOO\_ARRAY\_N}) und den eigentlichen
    Optionen (\texttt{FOO\_ARRAY\_1\_TEXT, FOO\_ARRAY\_1\_VALUE}). Diese treten
    dann je nach angegebener Anzahl mehrfach auf.

    Um einzelne Auspr"agungen auch innerhalb der Liste ausblenden zu k"onnen,
    ohne jedesmal die gesamte Liste umnummerieren zu m"ussen, empfiehlt sich
    die Verwendung einer Aktivierungsvariable (\texttt{FOO\_ARRAY\_1\_ACTIVE}).
    Diese muss dann im paketspezifischen Script gepr"uft werden.

    Mehrdimensionale Felder k"onnen in der Form \texttt{FOO\_ARRAY\_1\_SUBARRAY\_2\_VALUE})
    angegeben werden. Dazu m"ussen dann je Auspr"agung der ersten Dimension
    die Anzahl der Auspr"agungen der zweiten Dimension angegeben werden
    (\texttt{FOO\_ARRAY\_1\_SUBARRAY\_N}).


\subsection{Pr"ufen der Konfiguration}

    Sobald ein Anwender eine Konfiguration "uber das \eisfair-Men"u ("uber das
    edit-Script) ge"andert hat, wird diese auf G"ultigkeit "uberpr"uft. Dazu
    wird das Programm \jump{eischk}{eischk} benutzt, das im weiteren Verlauf
    dieses Kapitels n"aher beschrieben wird.

    \texttt{/etc/check.d/\package}\\
    \texttt{/etc/check.d/\package.exp}\\
    \texttt{/etc/check.d/\package.ext}

    In der Datei \texttt{/etc/check.d/\package} wird dabei die eigentliche
    Pr"ufung mit Abh"angigkeiten und Feldern definiert. Dazu stehen die
    in \texttt{/etc/check.d/base.exp} definierten Regul"aren Ausdr"ucke zur
    Verf"ugung.

    Sofern f"ur die "Uberpr"ufung einer eigenen Variable die vordefinierten
    Ausdr"ucke nicht ausreichend sind, so k"onnen in der Datei \texttt{/etc/check.d/\package.exp}
    eigene Regul"are Ausdr"ucke definiert werden. Die Namen dieser eigenen
    Ausdr"ucke m"ussen dabei den Paketnamen als Pr"afix enthalten (Beispiel:
    \PACKAGE\_VALUES).

    In der Datei \texttt{/etc/check.d/\package.ext} k"onnen mit einer Scriptsprache
    zudem weitergehende Pr"ufungen implementiert werden.


\marklabel{helpfile}{\subsection{Hilfedatei zur Konfiguration}}

    In den neueren Konfigurationseditoren (ECE)
    k"onnen dem Anwender weitergehende Hilfetexte angezeigt werden. Diese
    m"ussen dazu in der Datei \texttt{/var/install/help/\package} hinterlegt
    werden.

    Zeilenumbr"uche werden in dieser Datei mit dem Tag \tag{br/} gekennzeichnet,
    Kommentare k"onnen XML-Konform mittels \verb+<!-- + \textit{Kommentar} \verb+ -->+
    eingef"ugt werden.

    Der Hilfetext jeder einzelnen Variable wird mittels des Tags \tag{help}
    in dieser Datei hinterlegt.

    Die Datei hat damit folgendes Format:

\begin{example}
Beispiel f"ur eine \eisfair--Hilfedatei (Paket foo):
\begin{verbatim}
<!--
# -----------------------------------------------------------------------
# /var/install/help/foo - helptexts for package foo
#
# Creation:     2005-02-01  max
# Last Update:  2005-03-06  max
#
# Copyright (c) 2001-2014 the eisfair team, team(at)eisfair(dot)org
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# -----------------------------------------------------------------------
-->
<help name="FOO_GENERAL_SETTING">
    Hier koennen Sie eine Zeitspanne fuer das Paket foo
    definieren.
<br/><br/>
    Default: 60
</help>

<!-- Dies ist ein Kommentar -->

<help name="FOO_ARRAY_%_ACTIVE">
    Die Konfigurationsvariable FOO_ARRAY_%_ACTIVE dient
    zur Aktivierung bzw. Deaktivierung der einzelnen
    Eintraege.
<br/><br/>
    Default: yes
</help>

\end{verbatim}
\end{example}




\marklabel{applyconfig}{\section{Anwenden der Konfiguration}}

    Nach erfolgreicher Pr"ufung der Konfiguration muss diese aktiviert ("`apply"')
    werden. Dieser Vorgang wird vollst"andig im
    allgemeinen Edit--Script gekapselt.

    F"ur diesen Mechanismus m"ussen zwei paketspezifische Dateien bereitstehen:

    \texttt{/var/install/config.d/\package.sh}\\
    \texttt{/etc/init.d/\package}

    Die Datei \texttt{/var/install/config.d/\package.sh} dient dabei zum Generieren
    der Konfiguration der im Paket verwendeten Software aus der \eisfair\
    Konfigurationsdatei. Es handelt sich hier also um das Apply im eigentlichen
    Sinne.

    \achtung{Da eischk die Konfiguration nicht "uberpr"uft, wenn \texttt{START\_\PACKAGE='no'}
    gesetzt ist, darf in diesem Fall \textbf{kein} Neuschreiben der Konfiguration
    erfolgen!}

    Dieses Skript muss im Erfolgsfall den Wert 0 zur"uckgeben (\texttt{exit 0}).
    Im Fehlerfall muss ein Wert ungleich 0 zur"uckgegeben werden. Dies bewirkt,
    dass der Neustart des Basisdienstes "uber \texttt{/etc/init.d/\package}
    \textbf{nicht} ausgef"uhrt wird.

    Im Script \texttt{/etc/init.d/\package} muss der Befehl \texttt{restart} unterst"utzt
    werden. Dieser Befehl wird beim Aufruf als einziger Parameter "ubergeben.
    Bei Aufruf mit \texttt{restart} muss der Dienst neu gestartet bzw. es
    muss die Konfiguration so eingelesen werden, dass diese wirksam wird.

    Weitere Details dazu k"onnen in den  Kapiteln \jump{menufile}{Men"u} sowie
    \jump{boot}{Bootprozess} nachgeschlagen werden.


\marklabel{acfh}{\section{ACFH - Advanced Configuration File Handling}}

\subsection{ACFH Grundlagen}

Das Advanced Configuration File Handling (ACFH) bietet die M"oglichkeit, Generationen
von Konfigurationsdateien in einem Verzeichnis (\texttt{/etc/backup.d/}) sichern zu lassen.
Dies geschieht bei Nutzung des Skripts \texttt{/var/install/bin/edit} automatisch.

Die gesicherten Konfigurationsdateien tragen den Namen

 \texttt{\package.YYYY-MM-DD-HH-MI-SS},

also z.B. \texttt{base.2005-03-08-17-57-24}.

Die Anzahl der vorzuhaltenden Generationen von Konfigurationsdateien wird bestimmt
durch den Wert der Environmentvariablen \texttt{MAX\_BACKUP\_CONFIG} in der Datei
\texttt{/etc/config.d/environment}. "Ubersteigt die Anzahl der Konfigurationsdateien
f"ur ein Paket die in \texttt{MAX\_BACKUP\_CONFIG} angegebene Anzahl, so wird jeweils
die "alteste Konfigurationsdatei gel"oscht.

"Uber ein vorbereitetes Men"u des ACFH und entsprechende Skripts lassen sich
die Funktionen des ACFH aufrufen. An der Stelle base steht jeweils der entsprechende
Paketname.


\begin{example}
Beispiel:
\begin{verbatim}

Advanced base-configuration file handling.

        1: Restore configuration file from default directory

        2: Restore configuration file from backup directory

        3: Backup configuration file to backup directory

        4: Show difference between current and default configuration

        5: Show difference between current and a backup configuration

        6: Show difference between default and a backup configuration

        7: Show difference between two backup configurations

        0: Exit

Select (1-7, ENTER=Return 0=Exit)

\end{verbatim}
\end{example}

Die einzelnen Men"upunkte k"onnen allerdings nur dann erfolgreich
aufgerufen werden, wenn die entsprechenden Konfigurationsdateien
vorhanden sind.

\subsection{Einbinden von ACFH}

Die Einbindung von ACFH in ein Paket ist mit dem neuen Men"uformat
(XML-Men"u) sehr einfach geworden.

Um f"ur ein Paket das ACFH-Untermen"u aufrufen zu k"onnen sind nur
zwei Zeilen im entsprechenden Paket--Men"u notwendig.

\begin{verbatim}
<package>$package</package>
<menu file=setup.services.advancedconfig.menu">
           Advanced configuration file handling</menu>
\end{verbatim}

Das \tag{menu}--Tag muss in einer Zeile stehen.

"Uber das \tag{package}--Tag wird einerseits die Anzeige im Untermen"u
(siehe Beispiel oben paketname=base) gesteuert, andererseits auch
f"ur die aufzurufenden Skripte eingestellt, um welches Paket und
damit um welche Konfigurationsdateien es sich handelt.

Der "uber das \tag{package}--Tag eingestellt Paketname wird in der
Environmentvariablen \$PACKAGE gespeichert. Diese Variable darf
nicht anderweitig benutzt oder gar gel"oscht werden.
Daher steht im ACFH-Untermen"u selbst (Datei \texttt{setup.services.advancedconfig.menu})
kein \tag{package}--Tag.

\subsection{Men"us mit mehr als einem ACFH Untermen"u}

Eine spezielle Situation entsteht, wenn von einem Men"u aus
mehr als ein ACFH Untermen"u f"ur verschiedene Konfigurationsdateien
in \texttt{/etc/config.d/} aufgerufen werden soll.

Dies ist derzeit z.B. im Men"u "`Base configuration"' der Fall.
Hier ein Ausschnitt aus dem Men"u:

\begin{verbatim}

        3: Advanced base configuration file handling

        4: Advanced environment configuration file handling

\end{verbatim}

Hier wird das ACFH Untermen"u sowohl f"ur die Datei \texttt{/etc/config.d/base},
als auch f"ur \texttt{/etc/config.d/environment} aufgerufen.

"Uber das \tag{package}--Tag ist base als Paketname eingestellt. D.h.
der Aufruf f"ur base kann wie oben beschrieben erfolgen.

F"ur die Behandlung der Datei \texttt{/etc/config.d/environment} muss
die Option \texttt{package=\dq\dq} des \tag{menu}--Tag genutzt werden.

\begin{verbatim}
<menu package="environment" file="setup.services.advancedconfig.menu">
              Advanced environment configuration file handling</menu>
\end{verbatim}

Das <menu>--Tag muss in einer Zeile stehen.

Um die Quelldatei des Men"us einheitlich zu gestalten, wurde
auch der Aufruf des Men"us f"ur die Datei \texttt{/etc/config.d/base}
mit der optionalen Option \texttt{package=\dq\dq} versehen.

\begin{verbatim}
<menu package="base" file="setup.services.advancedconfig.menu">
               Advanced base configuration file handling</menu>
<menu package="environment" file="setup.services.advancedconfig.menu">
               Advanced environment configuration file handling</menu>
\end{verbatim}

Das \tag{menu}--Tag muss in einer Zeile stehen.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% eischk
\marklabel{eischk}{\section{Eischk}}

    Um die Konfigurationsfehler in Paketen m"oglichst auszuschliessen wird f"ur
    jedes Paket, welches eine Config--Datei besitzt, auch eine EISCHK--Datei
    angelegt: \texttt{/etc/check.d/\package}.
    In ihr sind alle Variablen der Konfigurationsdatei einzutragen. Der Aufbau
    gliedert sich dabei in 4 Spalten, die wie folgt belegt sind:


\subsection{VARIABLE}

    Diese Spalte gibt den Namen der zu "uberpr"ufenden Variable aus der Config--Datei an.
    Wenn es sich dabei um eine Variable handelt, die mehrmals mit verschiedenen
    Nummern auftauchen kann, wird an Stelle der Nummer ein Prozentzeichen (\%) als
    Platzhalter in den Variablennamen eingef"ugt. Mehrere Prozentzeichen zur "Uberpr"ufung
    mehrdimensionaler Arrays sind zul"assig.
    Sollten Variablen nur unter bestimmten Konfigurationsbedingungen ben"otigt werden,
    so sind sie als Optional zu kennzeichnen. Dazu wird vor die Variable ein "`+"' Zeichen
    vorangestellt. Soll ein gesamtes Array optional sein, dann ist der Z"ahlvariable
    (z.B. \texttt{FOO\_N}) ebenfalls ein "`+"' voranzustellen. In diesem Fall m"ussen aber auch die
    Array--Elemente als optional gekennzeichnet werden.

\begin{example}
Beispiele:
\begin{verbatim}
    optionale Variable:
    # Variable:           OPT_VARIABLE:  VARIABLE_N:    VALUE:
    +FOO_NAME             -              -              NONE

    optionales Element in einem Array:
    FOO_N                 -              -              NUMERIC
    ++FOO_%_VALUE1        -              FOO_N          NONE
    FOO_%_VALUE2          -              FOO_N          NONE

    optionales Array:
    +FOO_N                -              -              NUMERIC
    ++FOO_%_VALUE1        -              FOO_N          NONE
    ++FOO_%_VALUE2        -              FOO_N          NONE

    optionales mehrdimensionales Array:
    +FOO_N                -              -              NUMERIC
    ++FOO_%_VALUE_N       -              FOO_N          NUMERIC
    ++FOO_%_VALUE_%_VAL1  -              FOO_%_VALUE_N  NONE
\end{verbatim}
\end{example}


\subsection{OPT\_VARIABLE}

    Bei Bedarf kann in dieser Spalte eine Abh"angigkeit zu einer anderen Variable
    (\texttt{OPT\_VARIABLE}) definiert werden. Dadurch findet eine "Uberpr"ufung nur dann statt,
    wenn die \texttt{OPT\_VARIABLE} auf "`\texttt{yes}"' steht. Der Name der \texttt{OPT\_VARIABLE}
    darf keine Platzhalter f"ur Arrays (\%) enthalten. Gibt es keine \texttt{OPT\_VARIABLE}, ist hier
    ein "`--"' anzugeben. \\
    Ab dem base-Paket v1.3.0 d"urfen Platzhalter f"ur Arrays (\%) enthalten sein.


\begin{example}
Beispiel:
\begin{verbatim}
    # Variable:                 OPT_VARIABLE:               VARIABLE_N:      VALUE:
    --------------------------------------------------------------------------------------
    EISFAX_ANALOG_USE           START_EISFAX                -                YESNO
    EISFAX_ANALOG_N             EISFAX_ANALOG_USE           -                NUMERIC
    EISFAX_ANALOG_%_NAME        EISFAX_ANALOG_USE           EISFAX_ANALOG_N  NONE
    EISFAX_ANALOG_%_ACTIVE      EISFAX_ANALOG_USE           EISFAX_ANALOG_N  YESNO
    EISFAX_ANALOG_%_DEVICE      EISFAX_ANALOG_%_ACTIVE      EISFAX_ANALOG_N  NOTEMPTY
    EISFAX_ANALOG_%_SND         EISFAX_ANALOG_%_ACTIVE      EISFAX_ANALOG_N  YESNO
    EISFAX_ANALOG_%_SND_TO      EISFAX_ANALOG_%_SND         EISFAX_ANALOG_N  NONE
    EISFAX_ANALOG_%_SND_TYPE    EISFAX_ANALOG_%_SND         EISFAX_ANALOG_N  EISFAX_FTYPE
    EISFAX_ANALOG_%_PRN         EISFAX_ANALOG_%_ACTIVE      EISFAX_ANALOG_N  YESNO
    EISFAX_ANALOG_%_PRN_QUE     EISFAX_ANALOG_%_PRN         EISFAX_ANALOG_N  EISFAX_PQUEUE
    EISFAX_ANALOG_%_PRN_TYPE_GS EISFAX_ANALOG_%_PRN         EISFAX_ANALOG_N  YESNO
    EISFAX_ANALOG_%_PRN_DRV     EISFAX_ANALOG_%_PRN_TYPE_GS EISFAX_ANALOG_N  NONE
\end{verbatim}
\end{example}


\subsection{VARIABLE\_N}

    Steht in der ersten Spalte eine Variable mit einem Platzhalter \% im Namen, so
    wird hier die Variable angegeben, die die H"aufigkeit des Auftretens der Variable
    definiert. F"ur mehrdimensionale Array sind auch hier \% Zeichen im Namen zul"assig.
    Gibt es keine \texttt{VARIABLE\_N}, ist hier ein "`--"' anzugeben.

\begin{example}
Beispiel 1:
\begin{verbatim}
    # Variable:           OPT_VARIABLE:  VARIABLE_N:    VALUE:
    BIND9_N               -              -              NUMERIC
    BIND9_%_NAME          -              BIND9_N        DOMAIN
    BIND9_%_MASTER        -              BIND9_N        YESNO
    BIND9_%_NETWORK       -              BIND9_N        IPADDR
\end{verbatim}
\end{example}
\begin{example}
Beispiel 2 - mehrdimensionale Arrays mit optionalen Parametern:
\begin{verbatim}
    # Variable:           OPT_VARIABLE:  VARIABLE_N:    VALUE:
    ++BIND9_%_NS_N        -              BIND9_N        NUMERIC
    ++BIND9_%_NS_%_NAME   -              BIND9_%_NS_N   FQDN
\end{verbatim}
\end{example}


\subsection{VALUE}

    Diese Spalte enth"alt die "Uberpr"ufungrichtlinie des Inhaltes der Variable. Sie
    sollte im Interesse einer geringen Fehlerquote m"oglichst exakt die
    Eingabem"oglichkeiten eingrenzen. Dabei kann auf eine grosse Anzahl von fertigen
    Definitionen zur"uckgegriffen, aber auch mittels sogenannter "`Regular
    Expressions"' eigene erstellt werden.

    Folgende Definitionen sind bereits vorhanden:

\tablehead{\hline Name & Bedeutung & Beispiele \\ \hline}
\begin{supertabular}{|l|p{7cm}|p{4cm}|}
  NONE & Keine "Uberpr"ufung durchf"uhren &  \\
  NOTEMPTY & Inhalt darf nicht leer sein & 'foo- 12' \\
  NOBLANK & Es d"urfen keine Leerzeichen enthalten sein & 'foo' \\
  ENOBLANK & Kein Eintrag - oder Eintrag wie unter NOBLANK & '' / 'foo' \\
  NUMERIC & Nur Zahlen sind zul"assig & '1234' \\
  ENUMERIC & Kein Eintrag - oder Eintrag wie unter NUMERIC & '' / '1234' \\
  DOT\_NUMERIC & Zwei Zahlen durch einen Punkt getrennt & '12.5' \\
  EDOT\_NUMERIC & Kein Eintrag - oder Eintrag wie unter DOT\_NUMERIC & '' / '12.5' \\
  NUM\_HEX & Hexadezimale Zahl - startend mit 0x & '0xff12' \\
  NUM\_ANY & Zahlen in numerischer oder hexadezimaler Schreibweise & '123' / ''0xff12' \\
  YESNO & Nur yes oder no sind erlaubt & 'yes' / 'no' \\
  MACADDR & Mac Adresse einer Netzwerkkarte & '00:00:E8:83:72:92' \\
  HOSTNAME & Hostname bestehend aus Buchstaben, Zahlen und Bindestrich & 'foo-1' \\
  DOMAIN & Domainname inclusive Endung & 'bar.local' \\
  EDOMAIN & Kein Eintrag - oder Eintrag wie unter DOMAIN & '' / 'bar.local' \\
  FQDN & Vollst"andiger Internetname - host.domain.location & 'foo-1.bar.local' \\
  EFQDN & Kein Eintrag - oder Eintrag wie unter FQDN & '' / 'foo-1.bar.local' \\
  OCTET & Zahl im Bereich von 0 bis 255 & '128' \\
  IPADDR & G"ultige IP-Adresse, bestehend aus 4x OCTET & '192.168.0.128' \\
  EIPADDR & Kein Eintrag - oder Eintrag wie unter IPADDR & '' / '192.168.0.128' \\
  IPADDRESSES & Eine oder mehrere IP-Adressen durch Leerzeichen getrennt & '192.168.0.1 192.168.0.2 192.168.0.3' \\
  EIPADDRESSES & Kein Eintrag - oder Eintrag wie unter IPADDRESSES & '' / '192.168.0.1 192.168.0.2 192.168.0.3' \\
  IP\_ROUTE & Netzwerk, Netzmaske und Gateway durch Leerzeichen getrennt & '192.168.0.0 255.255.255.0 192.168.0.254' \\
  DNS\_SPEC & DOMAIN und IP-Adresse durch Leerzeichen getrennt & 'bar.local 192.168.0.1' \\
  MASK & Zahl zwischen 0 und 32 & '32' \\
  NETWORK & Kombination aus IP-Adresse, Trennstrich und Maske & '192.168.0.0/24' \\
  NETWORKS & Ein oder mehrer Netzwerke durch Leerzeichen getrennt & '192.168.0.0/24 192.168.1.0/24' \\
  ENETWORKS & Kein Eintrag - oder Eintrag wie unter NETWORKS & '' / '192.168.0.0/24 192.168.1.0/24' \\
  MULTIPLE\_NETWORKS & Ein oder mehrer Netzwerke durch Leerzeichen getrennt & '192.168.0.0/24 192.168.1.0/24' \\
  EMULTIPLE\_NETWORKS & Kein Eintrag - oder Eintrag wie unter MULTIPLE\_NETWORKS & '' / '192.168.0.0/24 192.168.1.0/24' \\
  IPADDR\_NETWORK & IP-Adresse und Netzwerk durch Leerzeichen getrennt & '192.168.0.1 192.168.1.0/24' \\
  EIPADDR\_NETWORK & Kein Eintrag - oder Eintrag wie unter IPADDR\_NETWORK & '' / '192.168.0.1 192.168.1.0/24' \\
  MAILADDR & Vollst"andige E-Mail Adresse & 'foo@bar.local' \\
  EMAILADDR & Kein Eintrag - oder Eintrag wie unter MAILADDR & '' / 'foo@bar.local' \\
  CRONTAB & Crontab Eintrag: Minute Stunde Tag Monat Wochentag & '15 3 * * fri' \\
  REL\_PATH & Relatives Verzeichnis & 'install/menu' \\
  E\_REL\_PATH & Kein Eintrag - oder Eintrag wie unter REL\_PATH & '' / 'install/menu' \\
  ABS\_PATH & Absolutes Verzeichnis & '/var/install/menu' \\
  E\_ABS\_PATH & Kein Eintrag - oder Eintrag wie unter ABS\_PATH & '' / '/var/install/menu' \\
  LOG\_INTERVAL & Als Werte sind daily, weekly oder monthly m"oglich & 'daily' / 'weekly' / 'monthly' \\
  PORT & Kommunikationsport im Bereich von 1 - 65535 & '3050' \\
  ETH\_BASE\_DEV\_NAME & Name der Ethernet Schnittstelle & 'eth0' \\
  ETH\_DEV\_NAME & Erweiterter Name der Ethernet Schnittstelle & 'eth0:3 \\
  TR\_BASE\_DEV\_NAME & Name der Tokenring Schnittstelle & 'tr2' \\
  TR\_DEV\_NAME & Erweiterter Name der Tokenring Schnittstelle & 'tr2:1' \\
  BR\_DEV\_NAME & Netzwerk Bridge Schnitstelle & 'br1:2' \\
  BOND\_BASE\_DEV\_NAME & Netzwerk Bonding Schnitstelle & 'bond0' \\
  BOND\_DEV\_NAME & Erweiterter Name der Netzwerk Bonding Schnitstelle & 'bond0:1' \\
  XEN\_BASE\_DEV\_NAME & XEN Bridge Netzwerk Schnitstelle & 'xen-br0' \\
  XEN\_BASE\_NAME & Erweiterter Name der XEN Bridge Netzwerk Schnitstelle & 'xen-br0:1' \\
  DUMMY\_DEV\_NAME & Platzhalter Schnittstelle (Dummy) & 'dummy0' \\
  IP\_NET\_NAME & Ethernet, Tokenring, Bridge oder Dummy Schnittstelle & 'eth0:2' / 'br1' / 'tr0' / 'dummy0' \\
  IP\_ROUTE & Netzwerkroute (network netmask gateway) & '192.168.1.0 255.255.255.0 192.168.1.254' \\
  IP\_ROUTE\_CIDR & Netzwerkroute (network/cidr gateway) & '192.168.1.0/24 192.168.1.254' \\
  \hline
  PASSWD   & Spezielle Regel, die die Sichtbarkeit im ECE beeinflusst. In der
             Ansicht wird der Wert der Option mit dem Zeichen '*' maskiert.
             Die Werteeingabe erfolgt "uber einen speziellen Dialog zur Passworteingabe. &
           '**********' \\
  READONLY & Spezielle Regel, die die Sichtbarkeit im ECE beeinflusst. In der
             Ansicht wird der Wert der Option inaktiv dargestellt. Eine
             Bearbeitung des Wertes wird vom Programm unterbunden. &  \\
  HIDDEN   & Spezielle Regel, die die Sichtbarkeit im ECE beeinflusst. In der
             Ansicht wird der Wert nicht dargestellt. &  \\
  \hline
\end{supertabular}
\\

    Da auch mit diesen M"oglichkeiten nicht jeder Anwendungsfall abzudecken ist, gibt es die
    M"oglichkeit, eigene "Uberpr"ufungen zu definieren. Diese werden durch die Buchstaben
    "`\texttt{RE:}"' f"ur Regular Expressions eingeleitet.

\begin{example}
    Beispiel:
\begin{verbatim}
    # Variable:           OPT_VARIABLE:  VARIABLE_N:    VALUE:
    COLOR                 -              -              RE:red|green|blue
\end{verbatim}
\end{example}

    So kann eine einfache Parameterauswahl realisiert werden. Alle anderen Eingaben als
    "`red"', "`green"' oder "`blue"' werden abgelehnt.
    Ein komfortablerer Weg stellt der Einsatz einer \texttt{/etc/check.d/\package.exp} Datei
    dar. In ihr k"onnen neben den Regular Expressions eigene Fehlermeldungen definiert werden.

    \achtung{Eigene Regular Expressions in der Datei \texttt{/etc/check.d/\package.exp} m"ussen
    den Paketnamen als Pr"afix enthalten.}

\begin{example}
    Beispiel:
\begin{verbatim}
    FOO_COLOR   = 'red|green|blue' : 'only red, green or blue are allowed'
\end{verbatim}
\end{example}

    In den regul"aren Ausdr"ucken k"onnen auch Referenzen auf bereits existierende
    Definitionen enthalten sein. Dadurch ist es einfacher, regul"are Ausdr"ucke zu
    konstruieren. Eingef"ugt werden die Referenzen einfach durch \texttt{'(RE:Referenz)'}.

\begin{example}
    Beispiel:
\begin{verbatim}
    FOO_IP_ROUTE    = '(RE:IPADDR)[[:space:]]+(RE:IPADDR)[[:space:]]+(RE:IPADDR)'
                      : 'no valid route specification (network netmask gateway)'

    FOO_DOT_NUMERIC = '(RE:NUMERIC).(RE:NUMERIC)'
                      : 'should be numeric (decimal) with dot e.g. 5.0'

\end{verbatim}
\end{example}

    Die speziellen Regeln PASSWD, READONLY und HIDDEN sind lediglich f"ur den ECE
    von Bedeutung. F"ur eischk stellen sie keine Einschr"ankung des Wertebereichs
    dar. Deshalb werden sie in der Datei \texttt{/etc/check.d/\package} h"aufig in
    Kombination mit anderen Regeln verwendet. Beispiel:

\begin{example}
    Beispiel:
\begin{verbatim}
    # Variable:           OPT_VARIABLE:  VARIABLE_N:    VALUE:
    FOO_DEBUG             -              -              YESNO
    FOO_DEBUG             -              -              HIDDEN
\end{verbatim}
\end{example}

\subsection{Fehlermeldungen}

    Findet die Pr"ufung einen Fehler, erfolgt die Ausgabe der Fehlermeldung auf
    folgende Art:

\begin{example}
\begin{verbatim}
    Error: wrong value of variable HOSTNAME: '' (may not be empty)
    Error: wrong value of variable MOUNT_OPT: 'rx' (user supplied regular expression)
\end{verbatim}
\end{example}

   Beim ersten Fehler wurde der Ausdruck in einem exp file definiert und
   ein Hinweis auf den Fehler wird mit ausgegeben. Im zweiten Falle wurde
   der Ausdruck direkt im *.txt File spezifiziert, deshalb gibt es keinen
   zus"atzlichen Hinweis auf die Fehlerursache.


\subsection{Definition regul"arer Ausdr"ucke}

    Regul"are Ausdr"ucke sind wie folgt definiert:

    Regul"arer Ausdruck: Eine oder mehrere Alternativen, getrennt durch
    '$|$', z.B. 'ro$|$rw$|$no'. Trifft eine der Alternativen zu, trifft der
    ganze Ausdruck zu (hier w"aren 'ro', 'rw' und 'no' g"ultige Ausdr"ucke).

    Eine Alternative ist eine Verkettung mehrerer Teilst"ucke, die einfach
    aneinandergereiht werden.

    Ein Teilst"uck ist ein "`Atom"', gefolgt von einem einzelnen '*', '+',
    '?' oder '\{min, max\}'. Die Bedeutung ist wie folgt:

\begin{itemize}
\item   'a*' - beliebig viele a's einschliesslich kein a
\item   'a+' - mindestens ein a, sonst beliebig viele a's
\item   'a?' - kein oder ein a
\item   'a\{2,5\} - zwei bis 5 a's
\item   'a\{5\} - 5 a's
\item   'a\{2,\} - mindestens 2 a's
\end{itemize}

Ein "`Atom"' ist ein
\begin{itemize}
\item  regul"arer Ausdruck eingeschlossen in Klammern, z.B. (a$|$b)+
       trifft auf eine beliebige Zeichenkette zu, die mindestens
       ein a oder b enth"alt, sonst aber beliebig viele und in
       beliebiger Reihenfolge
\item  ein leeres Paar Klammern steht f"ur einen "`leeren"'
       Ausdruck
\item  ein Ausdruck mit eckigen Klammern '[]' (siehe weiter unten)
\item  ein Punkt '.', der auf irgend ein einzelnes Zeichen zutrifft,
       z.B. '.+' trifft auf eine beliebige Zeichenkette zu, die
       mindestens ein Zeichen enth"alt
\item  ein '\^\,' steht f"ur den Zeilenanfang, z.B. '\^\,a.*' trifft auf
       eine Zeichenkette zu, die mit einem a anf"angt und in der
       beliebige Zeichen folgen, 'a' oder 'adkadhashdkash'
\item  ein '\$' steht f"ur das Zeilenende
\item  ein '\\' gefolgt von einem der Sonderzeichen
       '\^\,.[\$()$|$*+?\{'` steht f"ur genau das zweite Zeichen
       ohne seine spezielle Bedeutung
\item  ein normales Zeichen trifft auf genau das Zeichen zu,
       z.B. 'a' trifft auf genau 'a' zu.
\end{itemize}

Ein Ausdruck mit rechteckigen Klammern bedeutet folgendes
\begin{itemize}
\item  '[x-y]' - trifft auf irgend ein Zeichen zu, das zwischen
       x und y liegt, z.B. '[0-9]' steht f"ur alle Zeichen
       zwischen 0 und 9; '[a-zA-Z]' f"ur alle Buchstaben,
       egal ob gross oder klein

\item  '[\^\,x-y]' - trifft auf irgendein Zeichen zu, das nicht im
       angegebenen Intervall liegt

\item  '[:character\_class:] - trifft auf ein Zeichen der Zeichen-Klasse
       zu. Relevante Standardzeichenklassen sind: alnum, alpha,
       blank, digit, lower, print, punct, space, upper, xdigit.
\end{itemize}


\subsection{Beispiele f"ur Regul"are Ausdr"ucke}

    Sehen wir uns das mal an einigen Beispielen an:

    Numerisch: Ein numerischer Wert besteht aus mindestens einer, aber
    beliebig vielen Zahlen. Mindestens ein, aber beliebig viele dr"uckt man
    mit '+' aus, eine Zahl hatten wir schon als Beispiel. Zusammengesetzt
    ergibt das:

\begin{example}
\begin{verbatim}
    NUMERIC = '[0-9]+' oder alternativ
    NUMERIC = '[[:digit:]]+'
\end{verbatim}
\end{example}

    NOBLANK: Ein Wert, der keine Leerzeichen enth"alt ist ein beliebiges
    Zeichen (ausser dem Leerzeichen) und davon beliebig viele:

\begin{example}
\begin{verbatim}
    NOBLANK = '[^ ]*'
\end{verbatim}
\end{example}

    bzw. wenn der Wert zus"atzlich auch nicht leer sein soll:

\begin{example}
\begin{verbatim}
    NOBLANK = '[^ ]+'
\end{verbatim}
\end{example}

    Disk und Partition: G"ultige Bezeichner f"ur eine Disk beginnen mit hd
    bei IDE-Disks bzw sd bei SCSI-Disks. Dann folgen Buchstaben von a-z (a
    f"ur die erste Disk, b f"ur die 2., ...) und bei Partitionen die Zahlen
    1-8 (1-4 f"ur die ersten 4 Partitionen, die Prim"ar bzw. Extended (nur
    eine) sein k"onnen und 5-8 f"ur die logischen Partitionen innerhalb
    einer extended Partition). Die Ausdr"ucke sehen dann wie folgt aus:

\begin{example}
\begin{verbatim}
    DISK      = '(hd|sd)[a-z]'
    PARTITION = '(hd|sd)[a-z][1-8]'
\end{verbatim}
\end{example}

    Sehen wir uns das ganze nochmal am Beispiel der IP-Addresse an. Eine
    IP-Adresse besteht aus 4 Octets, die mit einem '.' getrennt sind. Ein
    Octet kann eine Zahl zwischen 0 und 255 sein. Definieren wir als
    erstes ein Octet. Es kann

\begin{tabular}[h!]{lr}
    eine Zahl zwischen 0 und 9 sein: &       [0-9]\\
    eine Zahl zwischen 00 und 99: &     [0-9][0-9]\\
    eine Zahl zwischen 100 und 199:&   1[0-9][0-9]\\
    eine Zahl zwischen 200 und 249: &  2[0-4][0-9]\\
    eine Zahl zwischen 250 und 255 sein: & 25[0-5]\\

\end{tabular}

    Da sich die ersten drei Teile stark "ahneln, kann man sie zusammenfassen:

\begin{itemize}
\item ein Zahl zwischen 0 und 199: 1?[0-9]?[0-9] (die ersten beiden
      Stellen k"onnen, aber m"ussen nicht da sein)
\end{itemize}

    Das ganze sind Alternativen, also fassen wir sie einfach mittels '$|$' zu
    einem Ausdruck zusammen: '1?[0-9]?[0-9]$|$2[0-4][0-9]$|$25[0-5]' und haben
    damit ein Octet. Daraus k"onnen wir nun eine IP-Adresse machen, 4
    Octets mit Punkten voneinander getrennt (der Punkt muss mittels {\em backslash}
    gequotet werden, da er sonst f"ur ein beliebiges Zeichen steht). Basierend
    auf der Syntax der Exp-Files sieht das ganze dann wie folgt aus:

\begin{example}
\begin{verbatim}
    OCTET  = '1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]'
    IPADDR = '((RE:OCTET)\.){3}(RE:OCTET)'
\end{verbatim}
\end{example}


\subsection{Erweiterte Pr"ufungen der Konfiguration}

    Manchmal ist es notwendig, komplexere "Uberpr"ufungen durchzuf"uhren.
    Beispiele f"ur solche komplexeren Dinge w"aren z.B. Abh"angigkeiten
    zwischen Paketen oder Bedingungen, die nur erf"ullt sein m"ussen,
    wenn Variablen bestimmte Werte annehmen.

    Um diese "Uberpr"ufungen durchf"uhren zu k"onnen, kann man in
    \texttt{/etc/check.d/\package.ext} kleinere Tests schreiben. Die Sprache
    besteht aus folgenden Elementen:

    \begin{enumerate}
    \item Schl"usselwoerter:

      \begin{itemize}
      \item Kontrollfluss:

        \begin{itemize}
        \item \texttt{if (expr) then statement else statement fi}
        \item \texttt{foreach var in set\_var do statement done}
        \item \texttt{foreach var in var\_n do statement done}
        \end{itemize}

      \item Aktionen:
        \begin{itemize}
        \item \texttt{warning "`\textit{warning}"'}
        \item \texttt{error   "`error"'}
        \item \texttt{fatal\_error "`fatal error"'}
        \item \texttt{set var = value}
        \item \texttt{stat (filename, res)}
        \item \texttt{split (string, set\_variable, character)}
        \end{itemize}
      \end{itemize}
    \item Datentypen:      strings, numerische Werte, Versionsnummern, Arrays
    \item Logische Operationen:    \texttt{$<$, ==, $>$, !=, !, \&\&, $||$, =}
    \end{enumerate}


\subsubsection{Kommunikation mit dem Nutzer: warning, error, fatal\_error}

    Mit Hilfe dieser drei Funktionen kann man Nutzer warnen, einen
    Fehler signalisieren oder die Pr"ufung sofort abbrechen. Das Format
    sieht wie folgt aus:

    \begin{itemize}
    \item \texttt{warning      "`text"'}
    \item \texttt{error        "`text"'}
    \item \texttt{fatal\_error "`text"'}
    \end{itemize}

    Im Text kann man auf Variablen Bezug nehmen, indem man einfach den
    Namen mit einem vorangestellten '\$' oder '\%' Zeichen in den Text
    schreibt (evtl. in {} eingeschlossen, um den Variablenamen vom
    umgebenden Text abzugrenzen). eischk versucht den darauffolgenden
    Text (Ziffern, Zahlen, '\_') als Variablennamen zu interpretieren
    und setzt bei einem vorangestellten '\$' den Inhalt der Variablen
    an dieser Stelle ein, wenn Sie definiert ist, bzw bei einem
    vorangestellten '\%' den vollst"andigen Namen der aktuellen
    \%-Variable. Sonst steht der originale Text da. Will man wirklich
    ein '\$' oder ein '\%' im Text haben, schreibt man '\$\$' bzw.
    '\%\%'.

\subsubsection{Zuweisungen}

    Ben"otigt man aus irgend einem Grund eine tempor"are Variable, kann
    man diese einfach mit \texttt{"`set var [= value]"'} anlegen. Die Variable
    darf keine Config--Variable sein. L"asst man den "`\texttt{= value}"' Teil weg,
    wird die Variable einfach auf "`yes"' gesetzt, so dass man sie
    hinterher einfach in einer if-Anweisung testen kann. Wird ein
    Zuweisungsteil angegeben, kann hinter dem Gleichheitszeichen alles
    stehen, normale Variablen, indizierte Variablen, Zahlen,
    Zeichenketten, Versionen.

\subsubsection{Arrays}

    Will man auf einzelne Elemente einer \%--Variablen (eines Arrays)
    zugreifen, kann man das wie gewohnt mit \%\_var[index] tun, wobei
    f"ur jedes \% Zeichen ein [ Index ] auftauchen muss.

\subsubsection{Abfragen von Eigenschaften einer Datei -- stat}

    \texttt{stat()} erm"oglicht es, Eigenschaften einer Datei abzufragen. Zur
    Verf"ugung gestellt wird im Augenblick lediglich die Gr"osse einer
    Datei, andere Attribute sind aber leicht hinzuzuf"ugen. Abfragen
    sehen wie folgt aus (wobei die verwendeten Parameter nur Beispiele
    sind):
\begin{example}
\begin{verbatim}
        stat ("unix/Makefile", test)
\end{verbatim}
\end{example}

    Danach sind zwei Variablen definiert:

    \begin{itemize}
    \item \texttt{test\_res}: Resultat des Systemrufs \texttt{stat()} ("`OK"',
      wenn Systemruf erfolgreich, sonst Fehlermeldung des Systemrufs)
    \item \texttt{test\_size}: Gr"osse der Datei
    \end{itemize}

    Das k"onnte dann z.B. so aussehen:

\begin{example}
\begin{verbatim}
        stat ("unix/Makefile", test)
        if ("$test_res" == "OK")
        then
                warning "test_size = $test_size"
        else
                error "Error '$test_res' while trying to get size of ..."
        fi
\end{verbatim}
\end{example}

\subsubsection{Auseinandernehmen von Parametern - split}

    Oftmals werden Variablen mit mehreren Parametern belegt, die dann
    in Startup--Scripten erst wieder auseinandergenommen werden. Will
    man diese bereits vorher auseinandernehmen und Tests mit ihnen
    durchf"uhren, nimmt man \texttt{split()}.

\begin{example}
\begin{verbatim}
        split (string, %_var, character)
\end{verbatim}
\end{example}

    Der String kann durch eine Variable, \%--Variable oder direkt als
    String angegeben werden. eischk zerlegt ihn an den Stellen, an
    denen das Trennzeichen auftaucht und erzeugt je eine Instanz der
    \%--Variablen. "Uber diese kann man dann hinterher Tests laufen
    lassen. Steht zwischen zwei Trennzeichen nichts, wird eine Instanz
    mit einer leeren Zeichenkette als Wert erzeugt. Ausnahme ist ' ',
    hier werden alle whitespaces konsumiert und keine leeren Variablen
    erzeugt.

    Sollen die bei der Zerlegung entstandenen Elemente in einem
    numerischen Kontext verwendet werden (z.B. als Index), muss das
    beim Aufruf von Split spezifiziert werden. Das geschieht durch das
    zus"atzliche Attribut 'numeric'. Der Aufruf sieht dann wie folgt
    aus:
\begin{example}
\begin{verbatim}
        split (string, %_var, character, numeric)
\end{verbatim}
\end{example}

\subsubsection{Kontrollfluss}

\begin{example}
\begin{verbatim}
        if (expr)
        then
                statement
        else
                statement
        fi
\end{verbatim}
\end{example}


    Eine klassische \texttt{if}--Konstruktion wie man sie kennt. Ist die
    Bedingung wahr, wird der \texttt{then}--Teil ausgef"uhrt, ist die Bedingung
    falsch, wird der \texttt{else}--Teil ausgef"uhrt.

    Will man Tests "uber \%--Variablen durchf"uhren, muss man jede einzelne
    Variable testen. Dazu gibt es das \texttt{foreach}--Statement in zwei Varianten:

\begin{example}
\begin{verbatim}
        foreach loop_var in set_var
        do
                statement
        done
\end{verbatim}
\end{example}

    Diese Schleife iteriert "uber alle \%--Variablen, angefangen bei eins
    bis zum in der dazugehoerigen (in \texttt{/etc/check.d/\package} stehenden)
    Variable\_N stehenden Index n. Die Laufvariable loop\_var nimmt
    dabei die jeweiligen Werte der \%-Variablen an.

    Das Statement kann dabei eine der oben beschriebenen Funktionen
    \texttt{if}, \texttt{foreach}, \texttt{warning}, \texttt{error} oder
    \texttt{fatal\_error} sein.

    Will man genau eine \%--Variable testen, kann man diese mittels
    \texttt{var\_\%\textit{\$index}} ausw"ahlen. Der index kann dabei eine normale
    Variable, ein String oder wiederum ein indiziertes Array sein.

\begin{example}
\begin{verbatim}
        foreach loop_var in var_n
        do
                statement
        done
\end{verbatim}
\end{example}

    Diese Schleife laeuft von 1 bis var\_n. Man kann die
    Schleifenvariable loop\_var dazu benutzen, um \_\% Variablen zu
    indizieren. Will man also nicht nur "uber eine \_\% Variable
    iterieren, sondern "uber mehrere gleichzeitig, nimmt man diese
    Variante der Schleife und verwendet die loop\_var zum Indizieren
    mehrerer \_\% Variablen.


\subsubsection{Expressions}

    Die Expressions erlauben so gut wie alles, was man von einer
    Programmiersprache gew"ohnt ist. Ein in einem Ausdruck
    auftauchender Wert 'val' kann eine Variable, ein String oder ein
    indiziertes Array sein. Variablen in Strings werden dabei wie oben
    beschrieben ersetzt. Ein Test auf die Gleichheit zweier Variablen
    k"onnte also so aussehen:
\begin{example}
\begin{verbatim}
        var1 == var2
        "$var1" == "$var"
\end{verbatim}
\end{example}

    Zu beachten ist dabei, dass der Vergleich in Abh"angigkeit vom Typ
    der Variable erfolgt, der in \texttt{/etc/check.d/\package} festgelegt
    wurde. Variablen, die als Typnamen einen mit NUM beginnenden Namen
    haben, erhalten einen numerischen Typ. Ist einer der beiden
    Variablen numerisch, erfolgt der Vergleich auf numerischer Basis,
    d.h. die Zeichenketten werden in Zahlen umgewandelt und dann
    vergleichen. Sonst erfolgt der Vergleich auf String--Basis; ein
    Vergleich von '05' und '5' geht ergibt ungleich, ein Vergleich von
    '18' und '9' ergibt '18' $<$ '9'.

    F"ur den Vergleich von Versionen wird das Hilfskonstrukt
    numeric(version) eingef"uhrt, welches den numerischen Wert f"ur
    einen Versionsstring f"ur Vergleichszwecke bestimmt .
    numeric(version) == sub\_version + 1000 * minor\_version + 10000 *
    major\_version:

    Eine vollst"andige Auflistung aller Ausdr"ucke ist in der folgenden
    Tabelle zu finden.

   \begin{tabularx}{\textwidth}[t]{|X|p{10cm}|}
       \firsthline
       \texttt{expr}                  &   true if\\
       \hline
       \texttt{id}                    &   id == 'yes'\\
       \texttt{val  == val}           &   strings/numerische Werte sind identisch\\
       \texttt{val  != val}           &   strings/numerische Werte sind verschieden\\
       \texttt{val  == number}        &   numerischer Wert von val == number\\
       \texttt{val  != number}        &   numerischer Wert von val != number\\
       \texttt{val  $<$  number}      &   numerischer Wert von val $<$  number\\
       \texttt{val  $>$  number}      &   numerischer Wert von val $>$  number\\
       \texttt{val  == version}       &   numeric(val) == numeric(version) \\
       \texttt{val  $<$  version}     &   numeric(val) $<$  numeric(version) \\
       \texttt{val  $>$  version}     &   numeric(val) $>$  numeric(version) \\
       \texttt{( expr )}              &   Ausdruck in Klammern ist wahr\\
       \texttt{expr \&\& expr}        &   beide Ausdr"ucke sind wahr\\
       \texttt{expr || expr}          &   mind. einer der beiden Audr"ucke ist wahr\\
       \lasthline
    \end{tabularx}


\section{Selbstdefinierte Dialoge im ECE}

    Um die Eingabe von Werten in der eisfair-Konfiguration noch einfacher und
    sicherer zu gestalten, sieht der Eisfair Konfigurationseditor (ECE) eine
    M"oglichkeit vor, die einfache Eingabezeile zur Parameterbearbeitung gegen
    selbstdefinierte Dialoge zu tauschen. In solchen Dialogen k"onnen Werte
    z.B. als Auswahllisten oder in jeder anderen denkbaren Form dem Anwender
    verf"ugbar gemacht werden.

    Damit der ECE einen Dialog verwendet m"ussen die folgenden Bedingungen
    erf"ullt sein:

    Zum einen muss in der Datei \texttt{/etc/check.d/\package} eine Pr"ufregel eingetragen
    werden, die der Variablen einen eindeutigen symbolischen Typnamen zuordnet.
    Kann das mit einer speziellen Typpr"ufung verbunden werden, dann steht ein
    solcher Name oftmals ohnehin zur Verf"ugung, anderenfalls muss eine ''leere''
    Pr"ufregel definiert werden. Beispiel:

\begin{example}
Beispiel f"ur eine Datei \texttt{/etc/check.d/\package} f"ur einen ECE-Dialog :
\begin{verbatim}
FOO_NETWORK       -      -           IPADDR
FOO_NETWORK       -      -           FOO_IP
FOO_DIR_N         -      -           NUMERIC
FOO_DIR_%_ACCESS  -      FOO_DIR_N   FOO_ACCESS
\end{verbatim}
\end{example}

    In dem oben aufgef"uhrten Beispiel wird angenommen, dass ein Paket FOO
    f"ur die Konfigurationsvariable FOO\_NETWORK einen speziellen Dialog zur Eingabe
    oder Auswahl einer IP-Adresse definieren m"ochte. Als Pr"ufregel kommt dabei die in
    der Basis definierte Regel IPADDR zum Einsatz, weshalb eine weitere Regel
    f"ur die selbe Variable eingef"ugt wurde, die lediglich einen Bezeichner
    (FOO\_IP) definiert (IPADDR w"are nicht eindeutig!).

    Zudem kennt die Konfiguration des FOO-Pakets die Variable FOO\_DIR\_\%\_ACCESS, welche
    ebenfalls einen Dialog erhalten soll. Hier gibt es aber bereits die paketspezifische
    Pr"ufregel FOO\_ACCESS, die eindeutig genug ist, um direkt als Bezeichner verwendet
    werden zu k"onnen.

    Selbstverst"andlich m"ussen f"ur FOO\_IP und FOO\_ACCESS ebenfalls Eintr"age
    in der Datei \texttt{/etc/check.d/\package.exp} angelegt werden.

\begin{example}
Beispiel f"ur eine Datei \texttt{/etc/check.d/\package.exp} f"ur einen ECE-Dialog :
\begin{verbatim}
FOO_IP                 = '(RE:NONE)'
                       : ''
FOO_ACCESS             = 'none|read|write'
                       : 'only none, read or write are allowed'
\end{verbatim}
\end{example}

    Zu guter letzt k"onnen nun im Verzeichnis \texttt{/var/install/dialog.d}
    shell-Skripte erstellt werden, die vom ECE verwendet werden sollen.
    Damit die Zuordnung zu den Variablen funktioniert sind die Namen der
    Skripte so zu w"ahlen, dass sie den zuvor definierten Typbezeichnern
    entsprechen.
    Im Beispiel w"aren dies: \texttt{FOO\_IP.sh} und \texttt{FOO\_ACCESS.sh} (wobei die
    Gross- Kleinschreibung zu beachten ist!).

    Die Skripte selbst k"onnen komplexe Programme enthalten und m"ussen dabei
    der CUI Skript-Spezifikation entsprechen. Die Syntax und das
    erforderliche Hintergrundwissen vermittelt das Dokument ''libcuidoc'',
    das ebenfalls auf der Webseite des eisfair-Projekts zu finden ist. Neben
    der C-API der libcui wird dort auch die Skript-Schnittstelle beschrieben
    und eine Referenz der verf"ugbaren Skript-Befehle geliefert.

    An dieser Stelle sollen lediglich Beispiele f"ur Skripte vorgestellt
    werden, mit denen man Auswahllisten im ECE realisieren kann. Diese
    Skripte k"onnen kopiert und auf vergleichbare F"alle angepasst werden:


\subsection{ece\_select\_list\_dlg}

    Der in der ecelib definierte Dialog ''ece\_select\_list\_dlg'' implementiert
    eine einfache Auswahlliste, die zentriert "uber dem Editorfenster angezeigt wird.
    Der Anwender kann dabei aus einer Reihe m"oglicher Werte w"ahlen und den
    gew"unschten Wert (z.B. mit Enter) best"atigen. Die Auswahl wird dann in die
    bearbeitete Konfigurationsvariable des ECE "ubertragen.

\begin{example}
Beispiel f"ur die Verwendung des Dialogs ece\_select\_list\_dialog :
\begin{verbatim}
#!/bin/sh

. /var/install/include/cuilib
. /var/install/include/ecelib

#-----------------------------------------------------------------
# exec_dailog
# ece --> request to create and execute dialog
#         $p2 --> main window handle
#         $p3 --> name of config variable
#-----------------------------------------------------------------
exec_dialog()
{
    local win="$p2"

    sellist="BLACK,RED,GREEN,BROWN,BLUE,MAGENTA,CYAN,LIGHTGRAY,"
             DARKGRAY,LIGHTRED,LIGHTGREEN,YELLOW,LIGHTBLUE,
             LIGHTMAGENTA,LIGHTCYAN,WHITE"

    ece_select_list_dlg "$win" "Colors" "$sellist"
}

#-----------------------------------------------------------------
# main routine
#-----------------------------------------------------------------

cui_init
cui_run

#-----------------------------------------------------------------
# end
#-----------------------------------------------------------------

exit 0

\end{verbatim}

Bei diesem Beispiel wird folgende Auswahlliste ausgegeben:
\begin{verbatim}
+----------[ Colors ]-----------+
|                               |
| +-------------------------+^| |
| | BLACK                   | | |
| | RED                     | | |
| |<GREEN =================>| | |
| | BROWN                   | | |
| | BLUE                    | | |
| | MAGENTA                 | | |
| | CYAN                    | | |
| +-------------------------+v+ |
|     [< OK >] [ Cancel ]       |
|                               |
+-------------------------------+
\end{verbatim}

\end{example}

\subsection{ece\_comment\_list\_dlg}

    Der Dialog ''ece\_comment\_list\_dlg'' ist eine Erweiterung des
    ''ece\_select\_list\_dlg'' Dialogs. Hier ist es m"oglich neben den
    Auswahloptionen Kommentare anzugeben, die gemeinsam mit den
    Auswahlwerten in einer zweispaltigen Auswahlliste dargestellt werden.
    Auf diese Weise sieht der Anwender nicht nur die Optionen (die f"ur
    sich gesehen u.U. vergleichsweise nichtssagend sind), sondern auch
    einen erkl"arenden Text, der die Auswahl erleichtert.


\begin{example}
Beispiel f"ur die Verwendung des Dialogs ece\_comment\_list\_dialog :
\begin{verbatim}
#!/bin/sh

. /var/install/include/cuilib
. /var/install/include/ecelib

#-----------------------------------------------------------------
# exec_dailog
# ece --> request to create and execute dialog
#         $p2 --> main window handle
#         $p3 --> name of config variable
#-----------------------------------------------------------------
exec_dialog()
{
    local win="$p2"

    sellist="option1|Dies ist Option1,option2|Dies ist Option2,
             option3|Dies ist Option3,option4|Dies ist Option4"

    ece_comment_list_dlg "$win" "Optionen" "$sellist"
}

#-----------------------------------------------------------------
# main routine
#-----------------------------------------------------------------

cui_init
cui_run

#-----------------------------------------------------------------
# end
#-----------------------------------------------------------------

exit 0

\end{verbatim}
Bei diesem Beispiel wird folgende Auswahlliste ausgegeben:
\begin{verbatim}
+-------------[ Optionen ]----------------+
|                                         |
| +-----------------------------------+^| |
| | option1    | Dies ist Option1     | | |
| | option2    | Dies ist Option2     | | |
| |<option3 ===| Dies ist Option3 ===>| | |
| | option4    | Dies ist Option4     | | |
| +-----------------------------------+v+ |
|          [< OK >] [ Cancel ]            |
|                                         |
+-----------------------------------------+
\end{verbatim}

\end{example}

\subsection{ece\_select\_cblist\_dlg}

    Der in der ecelib definierte Dialog ''ece\_select\_cblist\_dlg'' implementiert
    eine Auswahlliste unter Nutzung von Check Boxen, die zentriert "uber dem
    Editorfenster angezeigt wird.
    Der Anwender kann dabei einer Reihe m"oglicher Werte unter Nutzung der
    Cursortasten ansteuern und "uber die Space Taste ausw"ahlen. Ausgew"ahlte
    Werte werden mit [x] markiert. Nicht ausgew"ahlte Werte
    haben die Markierung [ ]. Die gew"unschten Werte k"onnen (z.B. mit Enter)
    best"atigen werden. Die Auswahl wird dann in die
    bearbeitete Konfigurationsvariable des ECE "ubertragen.

\begin{example}
Beispiel f"ur die Verwendung des Dialogs ece\_select\_cblist\_dialog :
\begin{verbatim}
#!/bin/sh

. /var/install/include/cuilib
. /var/install/include/ecelib

#-----------------------------------------------------------------
# exec_dailog
# ece --> request to create and execute dialog
#         $p2 --> main window handle
#         $p3 --> name of config variable
#-----------------------------------------------------------------
exec_dialog()
{
  local win="$p2"

  sellist='apache2,ldapserver,mail,mini_httpd,partimg,pure-ftpd,ssmtp'

  ece_select_cblist_dlg "$win" "Select one or more elements from a list" "$sellist"
}

#-----------------------------------------------------------------
# main routine
#-----------------------------------------------------------------

cui_init
cui_run

#-----------------------------------------------------------------
# end
#-----------------------------------------------------------------

exit 0
\end{verbatim}

Bei diesem Beispiel wird folgende Auswahlliste ausgegeben:
\begin{verbatim}
+-[ Select one or more elements from a list ]-+
|                                             |
|  [x] apache2                                |
|  [ ] ldapserver                             |
|  [ ] mail                                   |
|  [ ] mini_httpd                             |
|  [ ] partimg                                |
|  [x] pure-ftpd                              |
|  [ ] ssmtp                                  |
|                                             |
|           [<  OK  >]  [ Cancel ]            |
|                                             |
+---------------------------------------------+
\end{verbatim}

F"ur maximal 15 Elemente ist Platz auf einem 80/25 Display,
daher wird bei mehr als 15 Elemente eine Fehlermeldung erzeugt:
\begin{verbatim}
+----[ Checkbox selection ]----+
|                              |
|  Too many elements (16/15).  |
|                              |
|          [<  OK  >]          |
+------------------------------+
\end{verbatim}
Es k"onnen selbstverst"andlich auch l"angere Elemente angezeigt
und ausgew"ahlt werden, allerdings ist die Ausgabe auf 58 Zeichen
begrenzt. Die restlichen Zeichen werden durch ein .. angedeutet.

Beispiel:
\begin{verbatim}
+-----------[ Select one or more elements from a list ]------------+
|                                                                  |
|  [ ] dies ist ein ziemlich langer Text der auch ziemlich viel U..|
|  [ ] dies nicht                                                  |
|                                                                  |
|                      [<  OK  >]  [ Cancel ]                      |
|                                                                  |
+------------------------------------------------------------------+
\end{verbatim}

ACHTUNG:
Es wird nicht gepr"uft, ob ein Element mehrfach vorkommt.

Mittels der Variablen ECE\_SELECT\_CBLIST\_VAL\_SEPARATOR
kann der Separator der Select-Liste eingestellt werden.

ECE\_SELECT\_CBLIST\_VAL\_SEPARATOR=':'\\
setzt z.B. den Separator auf den Doppelpunkt.

\end{example}

