#

Installation and Configuration

#### The Kernel

Once upon a time there was the 1.2.13 kernel, which was included in the most distributions. This kernel did a goodjob for i4l, when no ISDN drivers existed in the kernel code, but the development stopped at version 0.7.3beta. So i4l users mostly used kernels younger than 1.3.68, the so-called "hacker kernels".

These days you should take a kernel version 1.3.97 or younger (there are kernel internal drivers available since kernel 1.3.69, but this thing only is stable enough since 1.3.97).

Now, while kernel 2.0 is released, we will talk about this kernel. Nowadays it is recommended to use kernel version 2.0.27, which cooperates flawlessly with isdn4k-utils-2.0. You should look for the kernel at your SunSite, e.g. at

      ftp.leo.org/pub/comp/os/linux/Linus/v2.0/

(e.g. linux-2.0.27.tar.gz; this kernel runs at the author's machine since months without any problems). And you also should fetch the new `modules` package:

      ftp.leo.org/pub/comp/os/linux/Linus/v2.0/modules-2.0.0.tar.gz

Handle the kernel as you are used to - have a look at the kernel-HOWTO:

      ftp.leo.org/pub/comp/os/linux/sunsite/docs/HOWTO/Kernel-HOWTO.gz

You should decompree your modules and install them as described in the Kernel-HOWTO.

If you want to use isdn4linux to drive an ISDN card you don't need to apply any more a patch to this kernel (only kernel 2.0.0 needed the two patches isdn4kernel-2.0-patch1+2). But: Most passive ISDN cards with Siemens chip set (Teles, Creatix, AVM, Elsa, ...) only work, if you use the driver package "HiSax". If you run such a card you must fetch this driver, too, and put it into`/usr/src`:

      ftp.franken.de/pub/isdn4linux/HiSax/

(e.g. version 1.5; read the README to learn which cards are supported!) Now patch it into the kernel:

      root:# cd /usr/src
      root:# tar zxfv HiSax_1.5.patch_for_2.0.tar.gz
      root:# patch -p <HiSax_1.5.patch_for_2.0
      root:# _

You must set now the following items while "make config" or its graphical relatives "make menuconfig" or "make xconfig" to compile the kernel:

    Code maturity level options":
      Prompt for development and/or incomplete code/drivers: No
    Section "General Setup":
      Networking support: Yes
    Section "Networking options":
      TCP/IP networking: Yes
      all other items are up to you
    Section "Network device support":
      Network device support: Yes
      PPP (point-to-point) support: Yes
      all other items are up to you
    Section "ISDN subsystem":
      Only if you need isdn4linux:
      ISDN support: Yes
      Support synchronous PPP: Yes (!)
      Use VJ compression with synchronous PPP: Yes
      Support audio via ISDN: Yes
      Support generic MP (RFC 1717): Yes
      Mark your own PC card here, too.

If this kernel later works properly you could think about defining some of the parts of it to modules instead of using a monolithic kernel.

#### ISDN Card Driver Software

If you only want to use a modem (analogous modem or ISDN modem) you may skip this section.

If you want to drive an ISDN card you also need the current version of Fritz Elfert's "isdn4kernel utilities". If you have an older version of isdn4linux you must update: the command "`isdnctrl pppbind`" must exist! Find out - type in `isdnctrl` and have a look at the available options.

      ftp.franken.de/pub/isdn4linux/isdn4k-utils-2.0.tar.gz

Put it into the /usr/src directory and unpack it by "`tar zxfv isdn4k-utils-2.0.tar.gz`". Now in the directory

      /usr/src/isdn4k-utils-2.0

you find all the files you need to operate i4l. Some Linux distributions lack of some important links, so you need to change some of the make files. These make files are all in the subdirectory `tools`. /usr/src/isdn4k-utils-2.0/tools/Makefile remove "isdnbutton-1.1" in the following line, if you don't have Motif - or you will get compiler errors. SUBDIRS=imon imontty-0.3 isdnlog-2.41 isdnbutton-1.1 tcltk [...] /usr/src/isdn4k-utils-2.0/tools/imontty-0.3/Makefile [...] LDFLAGS=-lncurses -lm [...] /usr/src/isdn4k-utils-2.0/tools/isdnlog-2.41/Makefile [...] LIB = -lgdbm [...] At first the programs need to be built. Therefore go into the `/usr/src/isdn4k-utils-2.0` directory, compile it by typing in "`make`", create the ISDN device files by "`make devices`" and finally install all executables by "`make install`" in the /sbin directory (also the man pages where they need to be).

You also need to define the card parameters - please read the ISDN4Linux manual

      /usr/src/linux/Documentation/isdn/README

These parameters will be set while booting or while loading the i4l modules.

## Configuration

Hint:
There are some large script files following. They are downloadable within this tutorial package - just click onto the script headlines! Remark for readers who are familiar with my tutorial:
The scripts have changed heavily. There is no longer a command `isdn`, all things are now handled by a script package named `connect`. This package can handle now modems, too!

### Configuration files

Two central files are used for setup and maintaining connections: The first one is called while machine boot-up, it lays in the startup directory and is named `rc.connect`. The other one is `connect` and is responsible for establishing and deleting connections and more.

Eine Reihe weiterer Dateien müssen angelegt werden. So ist für jeden Provider je eine Datei pro Einwahl-Telefonnummer herzustellen, in der alle wichtigen Daten enthalten sind. Die PPP-Dämonen benötigen überdies ein paar weitere Dateien. Das werden wir nun der Reihe nach besprechen.

There are also some more files necessary. So you need one file per provider and per dial-in number. And the PPP daemons need some more files, too. We will discuss this now.

If you did load down this WWW pages as package "leafsite.tar.gz", you find the scripts in the subdirectory "scripts".

### Some Pre Work

> If you have used the old "isdn" package before, stop the isdn system using

>         root:# <startup_path>/i4l stop (or "rc.isdn stop" or whatever)
>         root:# _

> (`<startup_path>` is the path, where all the system bootup files are located).

> Then remove (or save, if you like) some old files:

>         root:# rm <startup_path>/i4l (if you use a newer SuSE distribution)
>         root:# rm <startup_path>/rc.isdn
>         root:# rm /sbin/isdn
>         root:# rm /etc/i4l.provider (or /etc/i4l.config, if older "isdn" version)
>         root:# rm /etc/i4l.secrets  (or /etc/i4l.param, if older "isdn" version)
>         root:# _

You have to create some directories for the beginning:

      root:# mkdir /usr/lib/connect
      root:# mkdir /usr/lib/connect/providers
      root:# mkdir /var/lib/connect
      root:# _

### Provider Data

In `/usr/lib/connect/providers` for each provider and each dial-in number is needed. Files for isdn4linux and for modems look slightly different. Here some cutted examples - you can load down some examples, containing more explanations. Name these files as you like, but don't use a connect keyword (on, off, status, help, maxtries, route, device, all).

Beispiel für eine isdn4linux-Datei

      #!/bin/bash
      MODE=i4l
      PHONE=0891234567
      IP_ADDRESS=123.234.210.109
      OPTIONS_FILE=/etc/ppp/options.ipppd

Beispiel für eine Modem-Datei

      #!/bin/bash
      MODE=modem
      IP_ADDRESS=234.123.134.56
      DEVICE=ttyS1
      OPTIONS_FILE=/etc/ppp/options.pppd
      CHAT_SCRIPT="ABORT BUSY ABORT 'NO CARRIER' '' ATZ0 OK ATD0,08912345 CONNECT"

This files define some environment variables, which are used in the scripts described here. `MODE` tells connect whether it shall call i4l or drive a modem, `IP_ADDRESS` is the IP address of the remote you want to dial in, `OPTIONS_FILE` is the (i)pppd options file for this remote. isdn4linux needs the telephone number of the remote (`PHONE`), and pppd needs a chat script (`CHAT_SCRIPT`) and the serial port name (`DEVICE`), where the modem is connected.

You can load down a database with date for several universities and other providers.

By the way: I would be pleased to get the configuration file for your provider - just mail it!

### Default Values

Some data are loaded while system startup. Therefore you must write a configuration file. Here is mine:

    /usr/lib/connect/base
    #!/bin/bash
    # (c) 1997 Bernhard Hailer (GNU GPL V.2)

    # Edit this file for your needs

    # local settings
    # ==============

    # Fully qualified host name
    read MY_HOSTNAME </etc/HOSTNAME                          # read host's name
    # MY_HOSTNAME=foo.bar.com

    # Host phone number and MSN (EAZ) - replace by your numbers!
    MY_PHONE=817890032                                          # no leading zero!
    MY_EAZ=90032

    # Email address for fetching mail - replace by your address!
    MY_EMAIL_ADDRESS=dl4mhk@lrz.uni-muenchen.de

    # extra start commands for rc.connect (e.g. module loading)
    # ---------------------------------------------------------
    function Con_Start()
    {
      insmod /lib/modules/`/bin/uname -r`/misc/isdn.o
      insmod /lib/modules/`/bin/uname -r`/misc/hisax.o io=3,2,12,0xd80 HiSax_id=Teles0
      #insmod /lib/modules/`/bin/uname -r`/misc/teles.o io=0,12,0xd80,2 teles_id=Teles0
      #rmmod teles.o
      #insmod /lib/modules/`/bin/uname -r`/misc/teles.o io=0,12,0xd80,2 teles_id=Teles0
      return
    }

    # extra stop commands for rc.connect (e.g. module unloading)
    # ----------------------------------------------------------
    function Con_Stop()
    {
      rmmod hisax.o
      #rmmod teles.o
      sleep 1
      rmmod isdn.o
      return
    }

    # Default remote providers for regular connects
    DEFAULT_REMOTES="lrz-d1 lrz-d2"

    # default device where your modem is connected - no leading "/dev/"!
    DEFAULT_DEVICE="ttyS1"

    # Maximum number of dialin attempts
    declare -i DEFAULT_MAX_TRIES
    DEFAULT_MAX_TRIES=4

    # Maximum idle time before hangup (you should use a time of about 300 secs
    # here, because it is more expensive to dial often than to hold a line!)
    # This only works for isdn4linux connections.
    declare -i HUPTIMEOUT
    HUPTIMEOUT=300             # 5 min

The shell functions `Con_Start()` and `Con_Stop()` are called from the script `rc.connect` - these functions are very interesting if you load your ISDN subsystem as modules: enter here the commands for loading and unloading the modules. Examples for the Teles and the HiSax driver are printed here (I'm using currently HiSax 1.4 to drive a Teles 16.3 card).

Here also some default values are defined. `DEFAULT_REMOTES` contains the file names of the remotes which shall be called by default (if you define more than one, "connect" tries to call one after the other until the connection establishes). `DEFAULT_MAX_TRIES` says how often this should happen. `HUPTIMEOUT` is valid only for isdn4linux. Enter here after how many idle time isdn4linux shall hang up (modems: read the manual, please). And `DEFAULT_DEVICE` is the name of the serial interface the modem normally is connected.

We will discuss now this script `rc.connect`.

### What Happens While Booting

There are two possibilities Linux may boot. One is `simpleinit` (e.g. Slackware), the other one (more complicated, but also more flexible) is `sysvinit` (S.u.S.E. since 4.0, Debian, Caldera, Red Hat...). These two need different linking of the ISDN startup scripts.

#### simpleinit

`simpleinit` has its startup scripts in `/etc/rc.d/`. There are some single scripts. Important for us are the files `rc.M` (calls some startup scripts) and `rc.6` (reboot script). In this directory we set a new file named `rc.isdn`, which starts up the ISDN system.

You must create this file. Before this you must add the following to `/etc/rc.d/rc.M`, because this new file must be known by the booting system:

    /etc/rc.d/rc.M, section "# Initialize the NET subsystem."
      . /etc/rc.d/rc.inet1
      . /etc/rc.d/rc.connect    # <-- add this line!
      . /etc/rc.d/rc.inet2

#### sysvinit

Under `sysvinit` the start-up is completely different. Here the scripts are in the directory `/sbin/init.d/, /etc/init.d` or `/etc/rc.d/`. The scripts do have two functionalities: called with the argument "`start`" it starts up a part of the system, called with the argument "`stop`" it shuts down. This whole thing works with so-called "run levels"; level 0 is "system halt", level 1 is "single user mode", level 2 commonly is "multi user mode with network" and level 3 is "with xdm", and finally level 6 is running shutdown. The system calls the first three levels one after the other while startup (using "`start`"). In run level 6 they are called vice versa (using "`stop`").

This sequence is a bit "tricky": a "master script" looks into the directory of the run level (`./rc1.d, ./rc2.d, ./rc3.d` and so on) what to do. Therein are a lot of soft links to the scripts I wrote above. All links are named

      SnnScriptName

or

      KnnScriptName

with a number `nn`, which tells the master script in which order it has to call these scripts. So if we create a script - let's call it `rc.connect` again -, we must also set two links in the runlevel 2 directory `./rc2.d`:

      root:# cd /sbin/init.d/rc2.d  # (please verify path!!)
      root:# ln -s ../rc.connect K20rc.connect
      root:# ln -s ../rc.connect S20rc.connect
      root:# _

> Remark for S.u.S.E. users (version 4 and newer): A similar file exists here, named `i4l`, also there may exist a file `i4l_hardware`. These files must be removed, and also their calling scripts in `/sbin/init.d/rc2.d`. Of course so the `I4L_*` entries in the S.u.S.E. configuration file `/etc/rc.config` are obsolete now.

> Sorry for this inconvenience, but this is necessary to get a distribution independent package.

#### System Start and Stop

The file(s) you need for `simpleinit` or for `sysvinit` you can load down as usual in this tutorial. Because the script is awfully big I only descripe here how the ISDN subsystem is booted within this script (modems don't need startup sections). Just load and install this script as described above.

    /sbin/init.d/rc.connect (cutting)
      /sbin/isdnctrl verbose 0  # For debugging set to 2 (max. 4)
      # ISDN device drivers     ippp0 (PPP)
      /sbin/isdnctrl addif      ippp0
      /sbin/isdnctrl pppbind    ippp0 0
      /sbin/isdnctrl addphone   ippp0 out $PHONE      # dial-out number
      /sbin/isdnctrl addphone   ippp0 in $MY_PHONE    # my telephone no
      /sbin/isdnctrl eaz        ippp0 $MY_EAZ         # my MSN / EAZ
      /sbin/isdnctrl huptimeout ippp0 $HUPTIMEOUT     # defined in $BASE
      /sbin/isdnctrl secure     ippp0 on              # nobody may enter
      /sbin/isdnctrl l2_prot    ippp0 hdlc
      /sbin/isdnctrl l3_prot    ippp0 trans
      /sbin/isdnctrl encap      ippp0 syncppp
      /sbin/ifconfig ippp0 $MY_HOSTNAME pointopoint $IP_ADDRESS metric 1
      /sbin/route add default ippp0                   # interface definitions
      /sbin/ipppd /dev/ippp0 file $OPTIONS_FILE &
      /sbin/route del default
      ifconfig ippp0 down

Some people must edit the PATH in this script!

You must make this file executable by typing in `chmod 744` now.

You see: some of the environment variables defined above are used here! Some commands are remarkable: the "pppbind" command is against side effects, if more than one ipppd is started. If you don't call this command, all ipppd's use the passwords defined for the first one! The last two commands are also essential: only if no ipppd is up you can start a regular pppd for modems without problems!

By the way: We don't call the standard PPP daemon pppd 2.2.0[ef] here, but an especially patched version named "ipppd". This pppd is part of the ISDN4Linux package and is set while installation to /sbin. Anyway the PPP HOWTO and the pppd manpage is valid.

### More Files

To get this stuff working you must edit some more files as root: Either pppd or ipppd use the file `/etc/ppp/options` to load central configuration parameters. You can tell the (i)pppd with the command line argument `file` to load more files - we already have defined these files while building our remote files (`OPTIONS_FILE`). Here now `/etc/ppp/options`, which always is loaded:

    /etc/ppp/options
    # comment out the following three lines if you don't need
    # dynamic IP negotiation.
    ipcp-accept-local
    ipcp-accept-remote
    noipdefault
    # more pppd/ipppd options
    lock
    mru 1500
    mtu 1500
    debug
    -detach

If you don't dynamically receive your IP from your provider you must comment out the first three options. The rest is needed always. Now let's have a look at the extra option files. They are necessary, because

- the ipppd needs other options than the pppd,
- the options vary from provider to provider.

    sample file for the pppd
       pppd
    # /etc/ppp/options
    crtscts
    user hailer

    sample file for the ipppd
    # /etc/ppp/options for ipppd
    useifip
    -vjccomp
    -ac
    -pc
    -detach
    -bsdcomp
    -vj
    user hailer

Remark to option "`-vj`": If you don't define this option the system may get very angry. X Window sessions simply may hang, while common vt100 sessions may show some "kernel oopses". You may especially see the line "`Aiee, killing interrupt handler`". The option `useifip` is against side effects, if more than one ipppd is running.

    /etc/resolv.conf: (see provider database)
    search <what_you_need>
    nameserver <IP 1st nameserver>
    nameserver <IP 2nd nameserver>
    nameserver <IP 3rd nameserver>

You may enter here max. three nameservers. At "search" you can enter where short hostnames shall be searched. Example: If you have a "search" entry like this: `search lrz-muenchen.de` the command `ping sun3` will find `sun3.lrz-muenchen.de`.

    /etc/host.conf:
      order hosts bind
      multi on

    /etc/hosts:
      # For loopbacking.
      127.0.0.1       localhost
      # My own IP address
      192.168.1.1     machine.name                alias    # or your own IP address
      # (192.168.x.x is free, you always may use it!)
      # example entries
      129.187.10.22   sun3.lrz-muenchen.de        sun3     # (example remote)
      129.187.13.48   sunmailhost.lrz-muenchen.de getmail  # (example, for email)
      129.187.13.48   news.lrz-muenchen.de        getnews  # (example, for news)

### Authentification

You must authentificate yourself at the provider if you use PPP. Therefore two methods exist: PAP (Password Authentification Protocol) and CHAP (Challenge Authentification Protocol). PAP is widely used, but CHAP offers the provider more security. The secrets are in the file `/etc/ppp/pap-secrets` or `/etc/ppp/chap-secrets`. Attention! The`/etc/ppp/pap-secrets` file contains passwords and must be secured in any cases against unauthorized access!

      root:# chmod 600 /etc/ppp/pap-secrets (or /etc/ppp/chap-secrets)
      root:# _

#### PAP

    /etc/ppp/pap-secrets
      # Secrets for authentification using PAP
      # client          server           secret          IP addresses
      <provider_login>  <1st provider>   '<password>'    -
      <provider_login>  <2nd provider>   '<password>'    -

Remarks:

- It is recommended to nest the password in apostrophes. So no error appears if a "#" is in the password. (Thanks to Michael Matschilles `<mat@pascal.bmw.de>` for the hint!)
- In many cases it is easier to enter an asterisk "*" instead of the provider's name in the server column.

Don't forget to secure it with `chmod 600 /etc/ppp/pap-secrets`!

#### CHAP

Providers don't know your fully qualified hostname in most cases. So you have to rename your machine to the same name as your login at your provider - don't use a domain. But you can do it a more elegant way: give "`name <provider_login>`" as option while calling the ipppd (or make an entry in `/etc/ppp/options`). Instead of `/etc/ppp/pap-secrets` you must create a file `/etc/ppp/chap-secrets` like this (please note: there are two lines required per provider entry!):

    /etc/ppp/chap-secrets
      # Secrets for authentification using CHAP
      # client          server             secret       IP addresses
      <provider_login>  <1st provider>      <password>
      <1st provider>     <provider_login>   ""
      <provider_login>  <2nd provider>      <password>
      <2nd provider>     <provider_login>   ""

Don't forget to secure it with `chmod 600 /etc/ppp/chap-secrets`!

### Some Polish

Now you should bend the PPP log to an extra file for debugging. Therefore you should edit `/etc/syslog.conf` and add the following line (remark: use only tabulator characters, no spaces!):

      daemon.*                      /var/log/ppp-log

With this all the stuff the PPP daemon tells is saved to /var/log/ppp-log.

## Running

The system sometimes likes to connect more or less without any motivation to the provider. This is because of the nature of the system: If there is any IP packet (e.g. a name server request) Linux wants to get rid of it. Because this costs money we must switch it off. You could do it by deleting the default route, so that Linux now doesn't know any longer the way out.

The newer kernels since 1.3.100 have a something painful behavior: they set the default route automatically when a interface is defined. To prevent collisions you need to wait until a connect is completely built up (dialing, PPP handshake) before setting the default route. The following script does this. It is written so that you may call it more than once, so the first application (e.g. exchanging email) makes the connect, and the next applications don't need to open more lines. The last application cleans up: it hangs up and deletes the default route. Call this script as `/sbin/connect on` und `/sbin/connect off`. Here's only a very short example; you can load down a very sophisticated script by clicking onto the headline.

Put the script to /sbin and make it executable (route may be called only by "root"!):

      root:# chmod 744 /sbin/connect
      root:# _

    /sbin/connect
      #! /bin/bash

      PATH=/sbin:/usr/sbin:/bin:/usr/bin

      #  ISDN4Linux:

      case $1 in
        on)
          isdnctrl dial ippp0       #  connect
          sleep 5                   #  wait until open
          route add default ippp0   #  set route
          ;;
        off)
          isdnctrl hangup ippp0     #  disconnect
          route del default         #  and delete route
          ;;
        *)
          echo -e "\a Usage: 'isdn on' or 'isdn off'"
          ;;
      esac

      # Modem:

      IF_FILE=/var/lib/connect/interface
      case $1 in
        on)
          pppd connect "chat $CHAT_SCRIPT" file $OPTIONS_FILE /dev/$DEVICE &
          # the interface name was saved now by /etc/ppp/ip-up in IF_FILE.
          sleep 1
          echo "Sleeping 40 seconds for establishing connection..."
          sleep 40
          read INTERFACE <$IF_FILE
          route add default $INTERFACE
          ;;
        off)
          kill -HUP `cat /var/lock/LCK..$DEVICE`
          route del default
          ;;
      esac

Some people must edit the PATH in this script!

For modem usage INTERFACE must be retrieved with a trick: while startup of pppd the script `/etc/ppp/ip-up` is called with these arguments:

      ip-up interface device speed local_address remote_address

And we use that. We create a file ip-up:

    /etc/ppp/ip-up
    #!/bin/bash
    # This script is called by (i)pppd while starting up.
    # It is called this way:
    #   ip-up interface device speed local_address remote_address.
    #   So you can get the used interface by fetching $1
    echo $1 >/tmp/connect_interface.tmp

And so we have saved the interface name!

Hints for more experiments:

- The "isdnctrl dial ippp0" makes the connection - from there on it costs your money. We prevent connection failures this way because the system can hang after the connect took place (may be an error in ipppd). These hangs may appear if the system must dial after the connect command (telnet etc.).
- It is also important that you set the default route after completion of the connect. Otherways the kernel kills the route too early and sends messages like "`network not reachable`", if you want to connect to another computer.

Test:

      root:# connect
      Calling ippp0
      Dialing of ippp0 triggered
      Sleeping 8 sec for PPP handshaking...
      Line open - checking...
      :-) Line is ok - have fun!
      root:# telnet sun3
      [...]

(now log in as usual; later type in "exit" to finish)

      root:# connect off
      Last application stopped - closing line.
      prov0 hung up
      prov1 already closed! To force closing use "connect off all"
      root:# _

## What can "connect" do?

You just learned about the first two possibilities:

    "connect" (or "connect on")        connect default remote
    "connect off"                      disconnect

Important command:

    "connect off all"                  disconnects all channels

It is easy to connect to other remotes:

    "connect remote1 (on)"             connect to remote1
    "connect remote1 off"              and disconnect from it

If you enter more than one remotes in the command line, one after another will be tried, until a connection establishes.

    "connect remote1 remote2 remote3 ..."

You also may build more than one connection at the same time. Of course it is nonsense to set the defaultroute more than one time; you need to set special routes for each remote:

    "connect remote1 route Netz-IP"    connect via route
    "connect remote2 route default"    connect via defaultroute

The route must match the remote! You don't really need "route default.

If the dial-in ports of your provider are heavily loaded, you may want to have a maximum number of dial attempts:

    "connect remote1 maxtries number"

If you don't enter a "`maxtries`" the default value is taken from `/usr/lib/connect/base`.

And this is similar:

    "connect remote1 device ttySn"

So you tell "connect" where your modem is connected, if you want to use a modem. If you don't enter a "`device`" the default device is taken from `/usr/lib/connect/base`.

## More Utilities

There are some more very useful tools within the ISDN4Linux package. One is the X program "isdnmon" by Andreas Kool, wich shows the actual state of the S0 bus (free or connected). Michael Knigge's "imon" does the same in terminals. Also very useful is "isdnlog" by Andreas Kool, which gives information about the S0 bus activity. With "imontty" by Volker Goetz you can get a print-out of the ISDN card activity - very useful for scripts!

Have a look at the README by Fritz Elfert.