
\chapter{Installation, Bootprozess, Shutdown}

\marklabel{install}{\section{Paketinstallation}}

    Da es zur Installation einer Software meist nicht ausreicht, die
    Dateien an die richtige Stelle zu kopieren, sondern normalerweise
    zus"atzlich gewisse aktionen ausgef"uhrt werden m"ussen, gibt es auf
    \eisfair\ die Installationsskripte \texttt{preinstall.sh} und
    \texttt{install.sh}.

    Beide Skripte sind optional, m"ussen also nicht zwingend in jedem
    Paket enthalten sein.


\subsection{preinstall.sh}

    Bei der Paketinstallation wird nach dem Download des Pakets als
    erstes -- falls vorhanden -- das Skript \texttt{tmp/preinstall.sh} aus
    dem archiv extrahiert und ausgef"uhrt.

    In diesem Skript wird "ublicherweise als erster Schritt eine
    "uberpr"ufung der installierten Base-Version durchgef"uhrt. auf
    \tag{require-package} darf man sich hier nicht verlassen, da dieses
    Tag erst mit Base Version 1.0.3, und die Variante "uber Paketnamen
    erst seit Base Version 1.0.8 eingef"uhrt wurde.

\begin{example}
Beispiel f"ur die Pr"ufung der \eisfair\--Version in \texttt{preinstall.sh}:
\begin{verbatim}
required_base='1.6.3'

### check base version
if [ ! -f /var/install/bin/check-version ] ||
   [ `/var/install/bin/check-version base $required_base` = 'new' ]
then
    echo
    echo
    colecho "Wrong eisfair version!" rd w brinv
    colecho "Version must be $required_base or higher." rd w brinv
    colecho "Please update your eisfair system first." rd w brinv
    echo
    echo
    exit 1
fi
\end{verbatim}
\end{example}

    Dies ist auch die einzige Stelle, an der \texttt{echo}/\texttt{colecho}
    noch erlaubt ist. Die Verwendung von \texttt{mecho} ist hier nicht
    m"oglich, da ja gerade auf eine installierte base-Version gepr"uft
    wird und es beispielsweise bei \eisfair\ Version 1.0.3 noch kein
    mecho gab.

    Wie in diesem Beispiel ersichtlich kann die Installation im
    Fehlerfall "uber einen R"uckgabewert ungleich Null abgebrochen
    werden.

    Neben dieser Pr"ufung von Installationsvoraussetzungen k"onnen in
    diesem Skript Vorbereitungen zur Installation getroffen werden,
    beispielsweise die Deinstallation der vorhergehenden Version eines
    Pakets.

\begin{example}
Beispiel f"ur die Deinstallation einer alten Paketversion in
\texttt{preinstall.sh}:
\begin{verbatim}
package_name='foo'

### deinstall old package version
if [ -f "/var/install/deinstall/${package_name}" ]
then
    /var/install/deinstall/${package_name} update
fi
\end{verbatim}
\end{example}

    Ab der \eisfair\ Version 1.7.1 k"onnen Pakete bei einem update auch
    "uber die Standardfunktionen, messages, Meldungen schreiben, daf"ur ist eine
    Anpassung f"ur die Deinstallation notwendig. Auch sollte der Parameter
    update mit '\textendash\textendash' 2 Zeichen beginnen, \textendash\textendash{update}. Vorsicht bitte bei
    Paketen, die im Deinstall Skript noch 'update' stehen haben

\begin{example}
Beispiel f"ur die Deinstallation einer alten Paketversion in
\texttt{preinstall.sh}:
\begin{verbatim}
package_name='foo'

### deinstall old package version
if [ -f "/var/install/deinstall/${package_name}" ]
then
    /var/install/deinstall/del-package -p ${package_name} --update
fi
\end{verbatim}
\end{example}


    \textbf{achtung:} Bei der ausf"uhrung der \texttt{preinstall.sh} sind die
    Dateien des Pakets noch nicht installiert. auf Paketbestandteile kann
    daher nicht zugegriffen werden!


\subsection{install.sh}

    Sofern das Preinstall--Skript nicht mit einem Fehler abgebrochen hat,
    wird als n"achster Schritt das komplette Tar--archiv entpackt, und
    zwar immer vom Root-Verzeichnis "`/"' ausgehend, so dass alle Dateien
    im richtigen Verzeichnis landen.

    Danach wird -- falls vorhanden -- das Skript \texttt{/tmp/install.sh}
    ausgef"uhrt. Dieses Skript dient zur Installation des Pakets, also
    z.B. zur Erstellung von notwendigen symbolischen Links, zum Einf"ugen
    von Men"ueintr"agen oder zur "ubernahme der Konfiguration einer alten
    Paketversion.

\begin{example}
Beispiel f"ur die Installation eines \eisfair-Pakets:
\begin{verbatim}
#!/bin/sh
# -----------------------------------------------------------------------
# /tmp/install.sh - foo installation
#
# Creation   :  2009-12-31 starwarsfan
# Last update:  $Id: foo 22527 2010-01-02 16:51:38Z starwarsfan $
#
# Copyright (c) 2001-2013 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.
# -----------------------------------------------------------------------

# include eislib
. /var/install/include/eislib

# set package name
package_name=foo

# -----------------------------------------------------------------------
# Setup step 1
# -----------------------------------------------------------------------

# -----------------------------------------------------------------------
# add menu
# -----------------------------------------------------------------------
/var/install/bin/add-menu     \
        setup.services.menu   \
        setup.services.${package_name}.menu \
        "${package_name}"

# -----------------------------------------------------------------------
# Create default config
# -----------------------------------------------------------------------
if [ -f "/etc/config.d/${package_name}" ]
then
    update=true
fi

/var/install/config.d/${package_name}-update.sh


# -----------------------------------------------------------------------
# Aktivate configuration if necessary
# -----------------------------------------------------------------------
if "${update:-false}"
then
    /var/install/config.d/${package_name}.sh --quiet
    /etc/init.d/${package_name} start
fi


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


\marklabel{update}{\section{Update von Paketen}}

    Beim Update eines Pakets gibt es mehrere Dinge zu beachten. Besonders
    ist zu Ber"ucksichtigen, dass das Upgrade oftmals nicht von der
    letzten Version erfolgt, sondern dass ein Update auch von einer sehr
    viel "alteren Version erfolgen kann.

    In jedem Fall m"ussen beim Update die obsoleten Dateien der
    Vorversion entfernt werden. Zudem ist es f"ur \eisfair\--Pakete
    verpfichtend, dass die Konfiguration der Vorversion "ubernommen wird.
    Dabei m"ussen auch event"ulle "anderungen der Konfiguration (z.B.
    Hinzuf"ugen ne"ur Variablen) durchgef"uhrt werden.

    F"ur das Entfernen der Vorversion hat sich die Verwendung des
    Deinstall-Skripts der alten Version bew"ahrt. Da bei einem Update
    nicht alle Dateien gel"oscht werden d"urfen (z.B. die Konfiguration),
    muss das Deinstall--Skript einen Update-Modus kennen, d.h. es werden
    nicht alle Dateien gel"oscht, wenn der Parameter "`\texttt{update}"'
    "ubergeben wird. Ein Beispiel dazu ist im Deinstall-Script unter
    "`\jump{deinstall}{Deinstallieren von Paketen}"' zu finden.

    Bei der "ubernahme der Konfiguration gibt es mehrere F"alle. Im
    einfachsten Fall handelt es sich gar nicht um ein Update des Pakets
    sondern um eine Neuinstallation und es ist die Default--Konfiguration
    aus \texttt{/etc/default.d/} zu "ubernehmen.

    Sofern bereits eine Konfiguration einer Vorversion unter
    \texttt{/etc/config.d/} vorhanden ist, dient diese als Basis zur
    Erstellung der Konfiguration. Dabei m"ussen:

    \begin{itemize}
        \item Ne"u Konfigurationsvariablen, die in der alten
              Konfiguration noch nicht vorhanden sind, in die
              Konfiguration eingef"ugt werden.
        \item alte Konfigurationsvariablen, die es in der akt"ullen
              Paketversion nicht mehr gibt, entfernt werden.
        \item Konfigurationsvariablen, die sich ge"andert haben,
              angepasst werden. (z.B. Umbenennung, anpassung der
              Syntax...)
        \item Unver"anderte Konfigurationsvariablen "ubernommen werden.
    \end{itemize}

    F"ur diese "ubernahme der Konfiguration muss daher ein eigenes Skript
    erstellt werden, das "ublicherweise
    \texttt{/var/install/config.d/\package-update.sh} genannt wird.

\begin{example}
Beispiel f"ur ein Skript zur "ubernahme der Konfiguration eines
\eisfair\--Pakets:
\begin{verbatim}
#!/bin/sh
# -----------------------------------------------------------------------
# /var/install/config.d/foo-update.sh - paramater update script
#
# Creation   :  2009-12-31 starwarsfan
# Last update:  $Id: foo-update.sh 2342 2010-01-02 16:51:38Z starwarsfan $
#
# Copyright (c) 2001-2013 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.
# -----------------------------------------------------------------------

#exec 2> `pwd`/foo-update-trace$$.log
#set -x

# include configlib for using printvar
. /var/install/include/configlib

# set package name
package_name=foo

# -----------------------------------------------------------------------
# Set the default val"us for configuration
# -----------------------------------------------------------------------
START_FOO='no'


# -----------------------------------------------------------------------
# Read old configuration and rename old variables
# -----------------------------------------------------------------------
rename_old_variables()
{
    # read old values
    if [ -f /etc/config.d/${package_name} ]
    then
        /var/install/bin/backup-file --quiet ${package_name}
        . /etc/config.d/${package_name}
    fi
}

# -----------------------------------------------------------------------
# Write config and default files
# -----------------------------------------------------------------------
make_config_file()
{
    internal_conf_file=${1}
    {
    # -------------------------------------------------------------------
    printgpl --conf ${packageName} "2009-12-31" "starwarsfan"
    # -------------------------------------------------------------------


    # -------------------------------------------------------------------
    printgroup "Basic configuration"
    # -------------------------------------------------------------------
    printvar "START_FOO" "Use: yes or no"

    # -------------------------------------------------------------------
    printend
    # -------------------------------------------------------------------

    } > ${internal_conf_file}
    # Set rights
    chmod 0600 ${internal_conf_file}
    chown root ${internal_conf_file}
}

# -----------------------------------------------------------------------
# Create the check.d file
# -----------------------------------------------------------------------
make_check_file()
{
    printgpl --check ${package_name} '2009-12-31' 'starwarsfan' \
        >/etc/check.d/${package_name}
    cat >> /etc/check.d/${package_name} <<EOFG
# Variable       OPT_VARIABLE         VARIABLE_N           VALUE
START_FOO      -                -                   YESNO

EOFG

    # Set rights for check.d file
    chmod 0600 /etc/check.d/${package_name}
    chown root /etc/check.d/${package_name}

#    printgpl --check_exp ${package_name} '2009-12-31' 'starwarsfan' \
#        >/etc/check.d/${package_name}.exp
#    cat >> /etc/check.d/${package_name}.exp <<EOFG
#
#
#EOFG

    # Set rights for check.exp file
#    chmod 0600 /etc/check.d/${package_name}.exp
#    chown root /etc/check.d/${package_name}.exp

#    printgpl -check_ext ${package_name} '2009-12-31' 'starwarsfan' \
#        >/etc/check.d/${package_name}.ext
#    cat >> /etc/check.d/${package_name}.ext <<EOFG
#
#
#EOFG

    # Set rights for check.ext file
#    chmod 0600 /etc/check.d/${package_name}.ext
#    chown root /etc/check.d/${package_name}.ext
}



# -----------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------
# Write default config file
make_config_file /etc/default.d/${package_name}

# Update from old version
rename_old_variables

# Write new config file
make_config_file /etc/config.d/${package_name}

# Write check.d file
make_check_file

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

    Je nach Anwendungsfall muss dieses Script nat"urlich noch um die
    Behandlung weiterer F"alle wie "`L"oschen von Variablen"',
    "`Umbenennen von Variablen"' oder "ahnlichem erweitert werden.

    Es ist zu beachten, das bei array Variablen der erste Eintrag
    vorhanden sein muss, auch wenn das gesamte array nicht verwendet
    wird. Dies ist besonders bei Nutzung von joe oder vi an Stelle des
    ece als Editor relevant.

    Nach dem Neuschreiben der Konfiguration muss diese noch auf
    G"ultigkeit gepr"uft und der Dienst neu gestartet werden. Das kann
    mit einem direkten Aufruf des Edit--Skripts geschehen und gibt dem
    Anwender gleich die M"oglichkeit, die ver"anderte Konfiguration zu
    "uberarbeiten.


\marklabel{erweitertes-update}{\subsection{Erweitertes update}}

Bei Verwendung dieses Beispiels werden die Dateien unter
\texttt{/etc/default.d} und \texttt{/etc/check.d} nicht mit ausgeliefert,\\
da diese beim Verarbeiten des \texttt{\${package}-update.sh} erzeugt
werden.\\
Gleichzeitig wird bei den check Dateien mit 'Here-Documents' gearbeitet.

\begin{example}
\begin{verbatim}
#!/bin/sh
# -----------------------------------------------------------------------
# /var/install/config.d/eisfax-update.sh - parameter update script
#
# Creation:     2005-05-29 jv
# Last Update:  2006-06-11 hb
#
# Copyright (c) 2001-2013 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.
# -----------------------------------------------------------------------


#exec 2>/public/eisfax-update-trace$$.log
#set -x

package_name=eisfax

# include configlib for using printvar
. /var/install/include/configlib
. /var/lib/eisfax/eisfax.info

### ---------------------------------------------------------------------
### Set the default values for configuration
### ---------------------------------------------------------------------
START_EISFAX='no'

EISFAX_COUNTRY_CODE='49'
EISFAX_AREAa_CODE='40'
EISFAX_LONG_DISTANCE_PREFIX='0'
EISFAX_INTERNATIONAL_PREFIX='00'
EISFAX_MAX_DIALS='6'
EISFAX_ADMIN_USER_FAX_PASSWD=''
EISFAX_SAMBA_PRINTER_AUTO='yes'

EISFAX_ANALOG_USE='no'

EISFAX_ANALOG_N='1'

EISFAX_ANALOG_1_NaME=''
EISFAX_ANALOG_1_ACTIVE='no'
EISFAX_ANALOG_1_DEVICE='ttyS0'
EISFAX_ANALOG_1_FAaX_PRINTER_NAME='EISFAX'
EISFAX_ANALOG_1_CONFIGURE_AUTO='yes'
EISFAX_ANALOG_1_ID='+49.40.12345678'
EISFAX_ANALOG_1_LOCaL_IDENTIFIER='Fax-Station'
EISFAX_ANALOG_1_SERVER_NaME='EISFAX Server'
EISFAX_ANALOG_1_FAX_HEADER='von %%l %%n an %%d Seite %%P von %%T /'
EISFAX_ANALOG_1_HEAaDER_DaTE='%F %R'
EISFAX_ANALOG_1_RINGS_BEFORE_ANSWER='1'
EISFAX_ANALOG_1_SPEAKER_VOLUME='off'
EISFAX_ANALOG_1_SND='yes'
[...]

### ---------------------------------------------------------------------
### Read old configuration and rename old variables
### ---------------------------------------------------------------------
rename_old_variables()
{
    # read old val"us
    if [ -f /etc/config.d/${package_name} ]
    then
        /var/install/bin/backup-file --quiet ${package_name}
        . /etc/config.d/${package_name}
    fi

}

### ---------------------------------------------------------------------
### Write config and default files
### ---------------------------------------------------------------------
make_config_file()
{
    internal_conf_file=${1}
    {
    # -------------------------------------------------------------------
    printgpl --conf ${package_name} "2005-06-26" "hb"
    # -------------------------------------------------------------------

    # -------------------------------------------------------------------
    printgroup "Basic configuration"
    # -------------------------------------------------------------------

    printvar "START_EISFAX" "Start EISFAX server"
    printvar "EISFAX_COUNTRY_CODE" ""
    printvar "EISFAX_AREA_CODE"  ""
    printvar "EISFAX_LONG_DISTANCE_PREFIX" ""
    printvar "EISFAaX_INTERNATIONAL_PREFIX" ""
    printvar "EISFAX_MAX_DIALS" "Wieviele Wahlwiederholungen"
    printvar "" "ausgefuehrt werden sollen"

    printvar "EISFAX_ADMIN_USER_FAX_PASSWD" "Passwd for admin-user fax"

    printvar "EISFAX_SAMBA_PRINTER_AUTO" "Soll EISFAX die Samba config"
    printvar "" "aufrufen: yes or no"

    # -------------------------------------------------------------------
    printgroup "ANALOG settings"
    # -------------------------------------------------------------------

    printvar "EISFAX_ANALOG_USE" "Use: yes or no"

    printvar "EISFAX_ANALOG_N" "number of modems"

    # begin EISFAX_ANALOG_N
    idx=1

    while [ "${idx}" -le "${EISFAX_ANALOG_N}" ]
    do

        # section marker EISFAX_ANALOG_N
        if [ "${idx}" -le  "${EISFAX_ANALOG_N}"  ]
        then
            # -----------------------------------------------------------
            printgroup "EISFAX_ANALOG_${idx}"
            # -----------------------------------------------------------
        fi

        printvar "EISFAX_ANALOG_${idx}_NAME" \
                       "Use a name what ever you want, it's only for you"
        printvar "EISFAX_ANALOG_${idx}_ACTIVE" "Use only: yes or no"
        printvar "EISFAX_ANALOG_${idx}_DEVICE" "ttyS0 or ttyS1 or ttyS2"
        printvar "EISFAX_ANALOG_${idx}_FaX_PRINTER_NAME" \
                                               "Please, look at the Doku"
        printvar "EISFAX_ANALOG_${idx}_CONFIGURE_AUTO" \
                                              "Use: yes or no or scratch"
        printvar "EISFAX_ANALOG_${idx}_ID"
                                          "Your Fax-ID (+49.40.12345678)"
        printvar "EISFAX_ANALOG_${idx}_LOCAL_IDENTIFIER" \
                                          "Fax_Station name (fax header)"
        printvar "EISFAX_ANALOG_${idx}_SERVER_NAME" "EISFAX Server"
        printvar "EISFAX_ANALOG_${idx}_FAX_HEADER" \
                                 "von %%l %%n an %%d Seite %%P von %%T /"
        printvar "EISFAX_ANALOG_${idx}_HEADER_DATE" "%F %R"
        printvar "EISFAX_ANALOG_${idx}_RINGS_BEFORE_ANSWER" "1"
        printvar "EISFAX_ANALOG_${idx}_SPEAKER_VOLUME" \
                                          "off, quiet, low, medium, high"
        printvar "EISFAX_ANALOG_${idx}_SND" "Use: yes or no"
        [...]

    # end EISFAX_ANALG_N
    idx=`${EXPR_EXEC} ${idx} + 1`
    done

    # -------------------------------------------------------------------
    printend
    # -------------------------------------------------------------------

    } > ${internal_conf_file}
    # Set rights
    chmod 0600 ${internal_conf_file}
    chown root ${internal_conf_file}
}

### ---------------------------------------------------------------------
### Create the check.d file
### ---------------------------------------------------------------------
make_check_file()
{
    printgpl --check ${package_name} "2005-06-26" "jv" \
        >/etc/check.d/${package_name}
    cat >>/etc/check.d/${package_name} <<EOF
# Variable                          OPT_VARIABLE             VARIABLE_N        VALUE
START_EISFAX                        -                        -                 YESNO

EISFAX_COUNTRY_CODE                 START_EISFAX             -                 EISFAX_COUNTRYC
EISFAX_AREA_CODE                    START_EISFAX             -                 NONE
EISFAX_LONG_DISTANCE_PREFIX         START_EISFAX             -                 ENUMERIC
EISFAX_INTERNATIONaL_PREFIX         START_EISFAX             -                 ENUMERIC
EISFAX_MAX_DIALS                    START_EISFAX             -                 NUMERIC
EISFAX_aDMIN_USER_FaX_PaSSWD        START_EISFAX             -                 NOTEMPTY
EISFAX_SAMBA_PRINTER_AUTO           START_EISFAX             -                 YESNO

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_%_FaX_PRINTER_NAME    EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   EISFAX_SPRINTER_ERR
EISFAX_ANALOG_%_FaX_PRINTER_NAME    EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   WARN_EISFAX_SPRINTER_WARN
EISFAX_ANALOG_%_CONFIGURE_AUTO      EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   EISFAX_CONFIGURE
EISFAX_ANALOG_%_ID                  EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   NOTEMPTY
EISFAX_ANALOG_%_LOCAL_IDENTIFIER    EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   NOTEMPTY
EISFAX_ANALOG_%_SERVER_NaME         EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   NOTEMPTY
EISFAX_ANALOG_%_FaX_HEaDER          EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   NOTEMPTY
EISFAX_ANALOG_%_HEaDER_DaTE         EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   NOTEMPTY
EISFAX_ANALOG_%_RINGS_BEFORE_aNSWER EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   NUMERIC
EISFAX_ANALOG_%_SPEAKER_VOLUME      EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   EISFAX_SVOLUME
EISFAX_ANALOG_%_SND                 EISFAX_ANALOG_%_ACTIVE   EISFAX_ANALOG_N   YESNO
[...]
EOF

    # Set rights for check.d file
    chmod 0600 /etc/check.d/${package_name}
    chown root /etc/check.d/${package_name}


    printgpl --check_exp ${package_name} "2005-06-26" "jv" \
        >/etc/check.d/${package_name}.exp
    cat >>/etc/check.d/${package_name}.exp <<EOF
EISFAX_USER          = '([-,_[:lower:]0-9])+'
                     : 'no valid user name, because only the following charctershare allowed: a-z, 0-9, ., _ and -'
EISFAX_COUNTRYC      = '(RE:NUMERIC)(RE:NUMERIC)'
                     : 'Use numeric country code: 00 ... 99'
EISFAX_FTYPE         = '()|pdf|tif|ps|png'
                     : 'Use only: pdf, tif, ps or png'
EISFAX_RFTYPE        = 'pdf|tif|ps'
                     : 'Use only: pdf, tif, or ps'
EISFAX_RSEND         = '()|no|faxmaster|(RE:MAILADDR)|(RE:EISFAX_USER)'
                     : 'Use only: no or faxmaster or e-mail address'
EISFAX_FMaSTER       = 'yes|no|errors'
                     : 'Use only: yes, no, errors'
EISFAX_SVOLUME       = 'off|quiet|low|medium|high'
                     : 'Use only: off, quiet, low, medium or high'
EISFAX_PQUEUE        = 'pr[1-3]|repr[1-9]?[0-9]|usbpr[1-9]?[0-9]'
                     : 'Use only: pr1, pr2, pr3, repr1 ... repr99, usbpr1 ... usbpr99'
[...]
EOF

    # Set rights for check.exp file
    chmod 0600 /etc/check.d/${package_name}.exp
    chown root /etc/check.d/${package_name}.exp


    printgpl --check_ext ${package_name} "2005-08-31" "hb" \
        >/etc/check.d/${package_name}.ext
    cat >>/etc/check.d/${package_name}.ext <<EOF
if ( EISFAX_ANALOG_use == "yes" && EISFAX_isdn_use == "yes" )
   then
   error "Either EISFAX_ANALOG_USE _or_ EISFAX_ISDN_USE can be 'yes' "
fi

EOF

    # Set rights for check.ext file
    chmod 0600 /etc/check.d/${package_name}.ext
    chown root /etc/check.d/${package_name}.ext
}

### ---------------------------------------------------------------------
### Main
### ---------------------------------------------------------------------
# write default config file
make_config_file /etc/default.d/${package_name}

# update from old version
rename_old_variables

# write new config file
make_config_file /etc/config.d/${package_name}

# write check.d file
make_check_file

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


\marklabel{filelist}{\section{Dateiliste \package-files.txt}}

    Zu jedem Paket geh"ort auch noch eine Liste der enthaltenen Dateien
    und ihrer Rechte. Diese soll sp"ater u.\,a. zur "Uberpr"ufung der
    Dateirechte dienen. Das kann besonders f"ur Library Pakete wichtig
    werden, da das "Uberpr"ufen der Anwesenheit der
    Paketbeschreibungsdatei wenig "uber die Vollst"andigkeit der
    installierten Bibliotheken aussagt. Auch an eine Anpassung der
    Deinstallationsscripte ist in diesem Zusammenhang gedacht. Die Datei
    ist wie folgt aufgebaut:\\

\begin{verbatim}
    Filetype      b = Binaer, u = Unix-Text
    Rights        Zugriffsrechte
    User          Benutzer
    Group         Gruppe
    Package       Paketname
    File          Datei mir relativem Verzeichnis
\end{verbatim}

\begin{example}
Beispiel:
\begin{verbatim}
# -----------------------------------------------------------------------
# foo-files.txt - list of all files of package 'foo'
#
# Creation:     2004-11-17 jv
# Last update:  2006-05-30 max
# -----------------------------------------------------------------------
u 0755 root root foo tmp/install.sh
u 0755 root root foo tmp/preinstall.sh
b 0755 root root foo usr/bin/foorun
b 0644 root root foo usr/local/foo/bin/foo.so
u 0644 root root foo usr/local/foo/UDF/foosql.sql
u 0644 root root foo usr/share/doc/foo/changes.txt
u 0644 root root foo usr/share/doc/foo/foo.txt
\end{verbatim}
\end{example}



\marklabel{deinstall}{\section{Deinstallieren von Paketen}}

    Die Deinstallationsroutine muss in der Datei
    \texttt{/var/install/deinstall/\package} abgelegt werden und beinhaltet
    s"amtliche notwendigen Aktionen um ein Paket wieder sauber vom System
    zu entfernen.

    Die g"angigsten Punkte sind:

    \begin{itemize}
        \item Anhalten des Dienstes
        \item L"oschen der Konfiguration incl. der Backups, der
              Check-Dateien und des apply-Skripts
        \item Entfernen des Start-/Stop-Skripts incl. aller Symlinks
        \item Entfernen der Dokumentation, Dateiliste, Paket-Info-Datei
        \item Entfernen der Men"ueintr"age und der Men"udateien
        \item Entfernen von Cronjobs
        \item Entfernen von paketspezifischen Logdateien
        \item Entfernen des Deinstall-Skripts
        \item Entfernen der eigentlichen Software incl.
              Konfigurationsdateien und ggf. Datenbest"ande
    \end{itemize}

    Nicht entfernt werden d"urfen im allgemeinen:

    \begin{itemize}
        \item Benutzer und Benutzergruppen, sofern es noch Dateien gibt,
              die diesen geh"oren. Die Accounts sind in diesem Fall zu
              sperren.
        \item Dateien von Anwendern.
    \end{itemize}

    Eine abweichende Entscheidung muss im Einzelfall gekl"art werden.

    Sofern die Deinstallationsroutine auch zum Update eines Paketes
    genutzt wird, muss dort eine Sonderbehandlung erfolgen.

\begin{example}
Beispiel f"ur ein Skript zur "Ubernahme der Konfiguration eines
\eisfair-Pakets:
\begin{verbatim}
#!/bin/sh
# -----------------------------------------------------------------------
# /var/install/deinstall/foo - deinstall script
#
# Creation   :  2009-12-31 starwarsfan
# Last update:  $Id: foo 22527 2010-01-02 16:51:38Z starwarsfan $
#
# Copyright (c) 2001-2013 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.
# -----------------------------------------------------------------------

# Set package name
package_name=foo

# Set filelist
filelist=/etc/filelist.d/foo-files.txt

# Check if this is an update
if [ "${1}" = "--update" ]
then
    update=true

    # -------------------------------------------------------------------
    # add everything to this list what should _not_ be removed during an
    # update. This can be folders too, but let the bash expand their
    # content using an '*' like 'foo/bar/*'. The entries listet here must
    # be given on the file list of the package. all other stuff must be
    # remove by hand using an additional line like 'rm /foo/bar/bla.txt'.
    filesToLeave="etc/config.d/foo
                  etc/backup.d/foo*
                  etc/filelist.d/foo-files.txt
                  var/install/deinstall/foo
                  var/install/menu/setup.services.foo*"
else

    filesToLeave=''
fi

# -----------------------------------------------------------------------
# Remove package content except some special files if it's an update
# instead of a deinstallation
# -----------------------------------------------------------------------
while read id perm user group package file
do
    # ------------------------------------------------
    # Remove file only if it is not on the ignore list
    removeCurrentFile=true
    for currentFileToLeave in ${filesToLeave}
    do
        if [ "${currentFileToLeave}" == "${file}" ]
        then
            removeCurrentFile=false
            break
        fi
    done

    if ${removeCurrentFile}
    then
        case ${id} in
            b|u)
                if [ "${file}" != "tmp/install.sh" -a \
                     "${file}" != "tmp/preinstall.sh" ]
                then
                    rm -f /${file}
                fi
            ;;

            f)
                # Remove directories
                rmdir --ignore-fail-on-non-empty /${file} 2>/dev/null
            ;;
        esac
    fi
done < ${filelist}



# -----------------------------------------------------------------------
# Check files and default config must be removed separately because they
# are not on the file list if the package is used as it was created by
# create-package-new.sh, they are created dynamically during installation
# -----------------------------------------------------------------------
rm -f /etc/check.d/foo*
rm -f /etc/default.d/foo*



# -----------------------------------------------------------------------
# Stop remove for update only
# -----------------------------------------------------------------------
if "${update:-false}"
then
    exit 0
fi

# -----------------------------------------------------------------------
# Remove package from menu system / remove all menu and config files
# -----------------------------------------------------------------------
/var/install/bin/del-menu setup.services.menu setup.services.foo.menu

# -----------------------------------------------------------------------
# Remove config file
# -----------------------------------------------------------------------
rm -f /etc/config.d/foo
rm -f /etc/backup.d/foo*
rm -f /etc/filelist.d/foo-files.txt

# -----------------------------------------------------------------------
# Remove deinstall script
# -----------------------------------------------------------------------
rm -f /var/install/deinstall/foo

# -----------------------------------------------------------------------
exit 0
\end{verbatim}
\end{example}


\marklabel{boot}{\section{Bootprozess und Shutdown}}

    Wie bei Linux "ublich werden im Rahmen des Systemstarts die einzelnen
    Dienste "uber Kontrollskripte ("`Init--Skript"') im Verzeichnis
    \texttt{/etc/init.d/} gestartet und beim Shutdown wieder beendet.

    Um diesen Mechanismus nutzen zu k"onnen, ben"otigt man als erstes das
    Init--Skript namens \texttt{/etc/init.d/\package}. Dieses muss mehrere
    Startparameter verstehen \textendash\textendash zumindest \texttt{start}
    zum Starten des Dienstes sowie \texttt{stop} zum Stoppen des Dienstes.
    Auch sollte es den Parameter '\textendash\textendash{quiet}' verstehen,
    damit beim Aufruf mit diesem Parameter die 'echo' Ausgaben auf die
    Console unterdr"uckt werden.

    Um nun festzulegen, dass ein Dienst gestartet werden soll, und an
    welcher Stelle im Startprozess dies geschehen soll, muss dieses
    Skript unter \texttt{/etc/rc2.d/S\textit{nn}\package} verlinkt werden.

    Anstatt \texttt{rc2.d} k"onnen dabei je nach Runlevel die Verzeichnisse
    \texttt{rc0.d}, \texttt{rc2.d}, \texttt{rc6.d} und/oder \texttt{rcS.d} in Frage
    kommen, wobei f"ur die meisten Serverdienste wohl nur Runlevel 2
    relevant ist.

    Die Startposition wird dabei numerisch direkt hinter dem S angegeben
    und ist oben mit \texttt{\textit{nn}} symbolisiert. Die niedrigen Nummern
    werden dabei f"ur die f"ur den Serverbetrieb n"otigen Funktionen
    (z.B. SCSI-Treiber, Netzwerktreiber + Einstellungen) verwendet. Bei
    der Auswahl der Startposition f"ur das eigene Paket ist darauf zu
    achten, dass es sich harmonisch in die Startreihenfolge einf"ugt.

    ANALOG dazu wird das selbe Skript unter
    \texttt{/etc/rc2.d/K\textit{mm}\package} verlinkt, um das Beenden des
    Dienstes beim Shutdown zu steuern. Hier ist darauf zu achten, dass
    unkritische Dienste als erstes beendet werden.

    \achtung{\textbf{Grundsatz:} Die Summe der Start-- und Stopposition muss
                              immer 100 ergeben.}

    Das Skript /etc/init.d/functions stellt ab der \eisfair\--base 1.7.4
    die Funktionen wie sie im Nachfolgenden Beispiel benutzt werden bereit.


\begin{example}
Beispiel f"ur ein Init-Script:
\begin{verbatim}
#!/bin/sh
# -----------------------------------------------------------------------
# /etc/init.d/foo - init script for foo
#
# Creation:     2005-05-12  max
# Last Update:  2005-07-20  fabian
#
# Copyright (c) 2001-2013 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.
# -----------------------------------------------------------------------

# include functions
. /etc/init.d/functions

# include configuration
. /etc/config.d/foo

_do_start ()
{
    if ${forcestart:-false}
    then
        START_FOO=yes
    fi

    ### check if starting foo is allowed
    if [ "$START_FOO" = 'yes' ]
    then
        boot_mesg " * Starting foo ..."
        loadproc foo
    fi
}

_do_stop ()
{
    boot_mesg " * Stopping foo ..."
    killproc foo
}

_do_status ()
{
    statusproc foo
}

_do_usage ()
{
    echo "Usage: $0 [-q|--quiet] {start|forcestart|stop|restart}"
}

#--------------------------------------------------------------------------
# main
#--------------------------------------------------------------------------

while [ ${#} -gt 0 ]
do
    case "${1}" in
        -q|--quiet)
            _quiet=true
            shift
        ;;
        *)
            _action=${1}
            shift
        ;;
    esac
done

case "${_action}" in
    start)
        _do_start
    ;;
    forcestart)
        forcestart=true
        _do_start
    ;;
    stop)
        _do_stop
    ;;
    restart)
        _do_stop
        sleep 3
        _do_start
    ;;
    status)
        _do_status
    ;;
    *)
        _do_usage
        exit 1
    ;;
esac

exit 0

\end{verbatim}
\end{example}


    Im Beispiel ist neben den oben bereits erkl"arten Parametern
    \texttt{start} und \texttt{stop} der Parameter \texttt{restart} aufgef"uhrt,
    der f"ur die Verarbeitung einer Konfiguartions"anderung notwendig ist
    und im weiteren Verlauf dieser Dokumentation noch n"aher erkl"art
    wird.

    \hinweis{Es muss garantiert sein, dass der Dienst im init.d--Script
    startbar ist, auch wenn START\_FOO auf "`no"' gesetzt ist. Dies wird
    "uber den Parameter "`forcestart"' gew"ahrleistet.}

    Als weiteres Startskript gibt es \texttt{/etc/init.d/boot.\package}.
    Dieses Skript dient zum Aufr"aumen vor dem eigentlichen Starten des
    Dienstes und wird \textbf{vor} den Init--Skripten beim Systemstart
    ausgef"uhrt.

    F"ur dieses Skript ist ANALOG ein Link
    \texttt{/etc/init.d/boot.d/S\textit{nn}\package} zur Festlegung der
    Startposition zu erstellen. auch dieses Skript wird mit dem Parameter
    \texttt{start} aufgerufen.

    Hier k"onnen z.B. "ubriggebliebene tempor"are Dateien oder auch
    eventuell ver"anderte Zugriffsrechte einer Datei oder eines
    Verzeichnisses korrigiert werden.
