Debian and other Software Packages

⇐ table of contents | previous section | next section ⇒


Updating Debian

Keeping our Debian system up to date is very simple. We only need to configure apt for network updates. To this end, we install the apt-spy package and run apt-spy to find the fastest Debian mirrors. Then we edit /etc/apt/sources.list. Downloading and installing the latest Debian updates is then as simple as issuing the two commands apt-get update and apt-get upgrade.

Debian Packages for Finding Fast Debian Mirrors:

apt-spy

/etc/apt.sources:

# WOODY  main contrib non-free

# The following site was benchmarked at 14.49 kB/s
deb      ftp://ftp.skynet.be/debian/ woody main contrib non-free

# The following site was benchmarked at 14.29 kB/s
deb      ftp://ftp.stw-bonn.de/pub/mirror/debian/ woody main contrib non-free

# The following site was benchmarked at 14.29 kB/s
deb      ftp://toxo.com.uvigo.es/debian/ woody main contrib non-free

# Official Debian Mirror DE
deb      ftp://ftp.de.debian.org/debian woody main contrib non-free

# NON-US main contrib non-free

deb      http://non-us.debian.org/debian-non-US woody non-US/main non-US/contrib non-US/non-free

# SECURITY

deb      http://security.debian.org/ stable/updates main contrib non-free

Updating all Debian packages:

#> apt-get update
#> apt-get upgrade

⇐ table of contents | top ⇒


Local Debian Tree

The Debian distribution is currently organised along three releses: “stable” (a.k.a. “woody”), “testing” (a.k.a. “sarge”) and “unstable” (a.k.a. “sid”). Under normal circumstances and for most purposes we want to install packages from “woody” only, which corresponds to the default setup.

As its label implies, “woody” is stable and does therewith not represent the bleeding edge of new development. In most cases, this does not matter. In a few cases, however, we need or want a more recent package with new features, which may be available in “sarge” or “sid” but not in “woody”. We put these few packages in our local Debian tree, from which we can install them without upgrading the whole distribution.

Another reason for a local tree is that we might not always agree with the compile-time configuration of a Debian package and want to recompile it from source. The resulting binary package will then be stowed in the local Debian tree and overrides the default package.

/etc/apt/sources.list:

# LOCAL

deb      file:/usr/local/debian woody main
deb      file:/usr/local/debian sarge main

# WOODY  main contrib non-free

# The following site was benchmarked at 14.49 kB/s
deb      ftp://ftp.skynet.be/debian/ woody main contrib non-free

# The following site was benchmarked at 14.29 kB/s
deb      ftp://ftp.stw-bonn.de/pub/mirror/debian/ woody main contrib non-free

# The following site was benchmarked at 14.29 kB/s
deb      ftp://toxo.com.uvigo.es/debian/ woody main contrib non-free

# Official Debian Mirror DE
deb      ftp://ftp.de.debian.org/debian woody main contrib non-free

# NON-US main contrib non-free

deb      http://non-us.debian.org/debian-non-US woody non-US/main non-US/contrib non-US/non-free

# SECURITY

deb      http://security.debian.org/ stable/updates main contrib non-free

Creating a local Debian tree:

#> cd /usr/local
#> mkdir -p debian/dists/woody/main/binary-i386/local
#> mkdir -p debian/dists/sarge/main/binary-i386/local
#> mkdir debian/dists/woody/source
#> mkdir debian/dists/woody/rpm
#> mkdir debian/dists/sarge/source
#> mkdir debian/dists/sarge/rpm
#> touch debian/override.local.woody
#> touch debian/override.local.sarge
#> touch debian/dists/woody/main/binary-i386/Packages
#> touch debian/dists/sarge/main/binary-i386/Packages
#> apt-get update

The binary-i386/local directories are, where we stow the binary packages. In the source directories we install, unpack and compile the source packages, in the rpm directories we install and convert RedHat RPM packages.

Note: We should not resdistribute binary packages we have compiled within this framework since they may have non-standard dependencies, which are hard or impossible to satisfy in other (more standard) setups.

⇐ table of contents | top ⇒


GCC

Selecting a good version of the GNU C Compiler gcc is not unlike selecting a good wine. Most people don't know and don't care. But for those who know and care, there are big differences. The default version of gcc shipped with Debian, i.e. gcc 2.95.4, was a “vintage” version, whereas most later versions up and through gcc 3.0.x are more or less “fusel” versions. For this reason we want to replace gcc 3.0.4 from “woody” with gcc 3.2.1 from “sarge”.

The Debian Packages web-page is a good starting point to find all the packages we need (and their dependencies).

Debian Packages for gcc 3.2.1:

gcc-3.2           (1:3.2.1-0pre3)
gcc-3.2-base      (1:3.2.1-0pre3)
libgcc1           (1:3.2.1-0pre3)
cpp-3.2           (1:3.2.1-0pre3)
libc6             (2.2.5-14.3)
libc6-dev         (2.2.5-14.3)
locales           (2.2.5-14.3)
libdb1-compat     (2.1.3-7)
binutils          (2.13.90.0.10-1)
modutils          (2.4.19-3)

Downloading and Installing gcc 3.2.1 from “sarge”:

#> cd /usr/local/debian/dists/sarge/main/binary-i386/local
#>
#> wget http://ftp.de.debian.org/debian/pool/main/g/gcc-3.2/gcc-3.2_3.2.1-0pre3_i386.deb
#> wget http://ftp.de.debian.org/debian/pool/main/g/gcc-3.2/gcc-3.2-base_3.2.1-0pre3_i386.deb
#> wget http://ftp.de.debian.org/debian/pool/main/g/gcc-3.2/libgcc1_3.2.1-0pre3_i386.deb
#> wget http://ftp.de.debian.org/debian/pool/main/g/gcc-3.2/cpp-3.2_3.2.1-0pre3_i386.deb
#> wget http://ftp.de.debian.org/debian/pool/main/g/glibc/libc6_2.2.5-14.3_i386.deb
#> wget http://ftp.de.debian.org/debian/pool/main/g/glibc/libc6-dev_2.2.5-14.3_i386.deb
#> wget http://ftp.de.debian.org/debian/pool/main/g/glibc/locales_2.2.5-14.3_all.deb
#> wget http://ftp.de.debian.org/debian/pool/main/d/db1-compat/libdb1-compat_2.1.3-7_i386.deb
#> wget http://ftp.de.debian.org/debian/pool/main/b/binutils/binutils_2.13.90.0.10-1_i386.deb
#> wget http://ftp.de.debian.org/debian/pool/main/m/modutils/modutils_2.4.19-3_i386.deb
#>
#> cd /usr/local/debian
#> cat >> override.local.sarge
gcc-3.2         optional local
gcc-3.2-base    optional local
libgcc1         optional local
cpp-3.2         optional local
libc6           optional local
libc6-dev       optional local
locales         optional local
libdb1-compat   optional local
binutils        optional local
modutils        optional local
#> dpkg-scanpackages dists/sarge/main/binary-i386/local override.local.sarge > \
> dists/sarge/main/binary-i386/Packages
#>
#> apt-get update
#> apt-get upgrade
#> apt-get install gcc-3.2

⇐ table of contents | top ⇒


Debian Source Packages (Gendroolification ;-)

As most devoted zealots of the Gentoo Linux Metadistribution will fervently tell us, compiling our own linux distribution is not only etremely geeky but also speeds up things due to appropriate compiler optimisations.

Hmmmm ... well ... err ... we have some doubts that we will ever notice the speed difference between the i386- and the i686-compiled flavours of ls. In our opinion, processor optimisation makes sense for extremely computation and graphics intensive tasks only. Furthermore, we will probably never be able to cash-in the time we spend for the compilation for extremely large software packages like KDE before the next version comes out and we have to start compiling again. Until Debian sees the light and provides a binary distribution precompiled for the i686-type processors, the installation of source packages is not really worth the hassle — it is possible, though.

First we have to configure the system for this kind of “gendroolification”. To do so, we install some additional apt packages and pentium-builder:

Debian Packages for Gendroolification:

apt-show-source
apt-show-versions
pentium-builder

We have written a small shell script to simplify the configuration of the gcc-wrapper builder-cc. We can evaluate this script from either tcsh- or bash-compatible shells:

Pentium builder activation script:

#!/bin/sh
# bin/build-i686

if [ "$SHELL = "/usr/bin/tcsh" ]; then
  echo "setenv DEBIAN_BUILDGCCVER 3.2;"
  echo "setenv DEBIAN_BUILDARCH i686;"
else
  echo "export DEBIAN_BUILDGCCVER=3.2"
  echo "export DEBIAN_BUILDARCH=i686"
fi
exit

Now we simply add for (almost) all deb entries in /etc/apt/sources.list a corresponding deb-src entry, so that we can download the source packages with apt.

/etc/apt/sources.list:

# LOCAL

deb      file:/usr/local/debian woody main
deb      file:/usr/local/debian sarge main

# WOODY  main contrib non-free

# The following site was benchmarked at 14.49 kB/s
deb      ftp://ftp.skynet.be/debian/ woody main contrib non-free
deb-src  ftp://ftp.skynet.be/debian/ woody main contrib non-free

# The following site was benchmarked at 14.29 kB/s
deb      ftp://ftp.stw-bonn.de/pub/mirror/debian/ woody main contrib non-free
deb-src  ftp://ftp.stw-bonn.de/pub/mirror/debian/ woody main contrib non-free

# The following site was benchmarked at 14.29 kB/s
deb      ftp://toxo.com.uvigo.es/debian/ woody main contrib non-free
deb-src  ftp://toxo.com.uvigo.es/debian/ woody main contrib non-free

# Official Debian Mirror DE
deb      ftp://ftp.de.debian.org/debian woody main contrib non-free
deb-src  ftp://ftp.de.debian.org/debian woody main contrib non-free

# NON-US main contrib non-free

deb      http://non-us.debian.org/debian-non-US woody non-US/main non-US/contrib non-US/non-free
deb-src  http://non-us.debian.org/debian-non-US woody non-US/main non-US/contrib non-US/non-free

# SECURITY

deb      http://security.debian.org/ stable/updates main contrib non-free

To download, compile and install a source package, e.g. gnupg (and the packages it depends on), we use apt-get, dpkg-buildpackage and dpkg.

Getting, compiling and installing Debian source packages:

#> cd /usr/local/debian/dists/woody/main/source
#>
#> eval `build-i686`
#>
#> apt-get source gnupg
#> apt-get build-dep gnupg
#>
#> apt-get source zlib1g
#> apt-get build-dep zlib1g
#> cd zlib-1.1.4
#> dpkg-buildpackage
#> cd ..
#> mv zlib1g*.deb ../binary-i386/local
#> echo "zlib1g optional local" >> /usr/local/debian/override.local 
#> echo "zlib1g-dev optional local" >> /usr/local/debian/override.local 
#> rm -rf zlib*
#>
#> apt-get source libgdbmg1
#> apt-get build-dep libgdbmg1
#> cd gdbm-1.7.3
#> dpkg-buildpackage
#> cd ..
#> mv libgdbmg1*.deb ../binary-i386/local
#> echo "libgdbmg1 optional local" >> /usr/local/debian/override.local
#> echo "libgdbmg1-dev optional local" >> /usr/local/debian/override.local
#> rm -rf gdbm*
#>
#> cd gnupg-1.0.6
#> dpkg-buildpackage
#> cd ..
#> mv gnupg*.deb ../binary-i386/local
#> echo "gnupg optional local" >> /usr/local/debian/override.local
#> rm -rf gnupg*
#>
#> cd /usr/local/debian
#> dpkg-scanpackages dists/woody/main/binary-i386/local override.local > \
> dists/woody/main/binary-i386/Packages
#>
#> apt-get update

Lather, wash, rinse, repeat.

⇐ table of contents | top ⇒


XFree86 4.0.0 Framebuffer Server

Thanks to our little framebuffer-hack, it is possible to run XFree86 via the framebuffer device — albeit without graphics acceleration. Debian manages to puzzle together a surprisingly well done configuration with every schnickschnack we need. The only thing we need to do is to enter the path for our truetype fonts (and apply some minor cosmetic corrections).

The small test program glxgears runs at roughly 290 fps (7 fps in fullscreen mode). The framebuffer does, however, not really draw every frame to the screen, so the wheels don't run smoothly but hang and jump.

Debian packages for the XFree86 4.0.0 framebuffer server:

xfree86-common
xserver-xfree86

⇐ table of contents | top ⇒


Xi Graphics Accelerated-X Server

Xi Graphics offers an Accelerated-X Server for the IBM Thinkpad A31p. The license for the LX version with 3D OpenGL X acceleration costs USD 149.–– (other versions also available).

The XiG tar-ball contains two RedHat RPM archives, i.e. a kernel module package xsvc_3.0-39.i386.rpm and the driver package Summit_LX-Gold-2.2-6.i386.rpm. First we convert, extract, compile and install the kernel module.

Compilation and installation of the XiG kernel module:

#> alien xsvc_3.0-39.i386.rpm
#> dpkg -i xsvc_3.0-39_i386.deb
#> cd /usr/src/xig/xsvc/
#> make clean
#> make
#> make install
#> modprobe xsvc

modprobe barfs an informal message that loading this module will taint the kernel. This can be safely ignored. It just means that we should not bother the linux kernel developers, if and when things go wrong with the kernel after loading this module.

Modprobe warning about XiG kernel module:
 
Warning: loading /lib/modules/2.4.18/misc/xsvc.o will taint the kernel: no license

More important is the output of the module itself. If everything is okay, the following message should be written to the system log-files (default Debian location: /var/log/messages):

XiG kernel module initialisation messages:

[date] [some kernel]: xsvc: v3.0 (devrel@xig.com) [$XiGDate: 2002/10/24 20:31:44 $]
[date] [some kernel]: xsvc: Intel 845, 64MB at 0xe0000000 (1f000217/01)

Unfortunately, neither alien nor the Debian version of rpm can handle the driver package Summit_LX-Gold-2.2-6.i386.rpm. So we have to unpack and install it manually. Using the Debian package stow, we can even be semi-clever about it.

Debian package for stowing foreign software packages:

stow

Installing the XiG Accelerated-X server:

#> mkdir /tmp/TMP
#> mkdir -p /usr/local/packages/XiG/share/doc/XiG
#> rpm2cpio Summit_LX-Gold-2.2-6.i386.rpm | (cd /tmp/TMP; cpio --extract \ 
> --make-directories --no-absolute-filename --preserve-modification-time)
#> tar cf - /tmp/TMP/usr/. | (cd /usr/local/packages/XiG; tar xf -)
#> mv README.* *.pdf *.txt /usr/local/packages/XiG/share/doc/XiG
#> cd /usr/local/packages/XiG/X11R6/lib/X11/AcceleratedX/etc
#> ln -s Xlicense.demo Xlicense
#> cd ../../..
#> cp X11/AcceleratedX/OpenGL/usr/lib/libGL* .
#> cd /etc/X11
#> ln -sf /usr/X11R6/bin/Xaccel X
#>
#> dpkg-divert --rename --divert /usr/X11R6/lib/@@@libGL.so.1.2.distrib \
> /usr/X11R6/lib/libGL.so.1.2
#> dpkg-divert --rename --divert /usr/X11R6/lib/@@@libGLU.so.1.3.distrib \
> /usr/X11R6/lib/libGLU.so.1.3
#>
#> cd /usr/local/stow
#> ln -s ../packages/XiG .
#> stow -v --target=/usr XiG
#> ldconfig; ldconfig
#> rm -rf /tmp/TMP

Note: We actually have to run ldconfig twice. In the first run, only the links libGL.so.1.3 and libGLU.so.1.3 are created. In the second run libGL.so.1 and libGLU.so.1 are set.

Although the hardware specs claim a 4xAGP bus, the server locks hard if 4xAGP is configured in XSetup. Anyway, with this server, glxgears runs at impressive 1393 fps (66 fps in fullscreen mode). Contrary to what is written in the XiG documentation, we see no speed difference between Debian's and XiG's versions of the OpenGL libraries.

If we want to switch back to the XFree86 server, we just update the symlink in /etc/X11:

Switching back to the XFree86 server:

#> cd /etc/X11
#> ln -sf /usr/X11R6/bin/XFree86 X

Removing the XiG server is also simple and easy:

Removing the XiG Accelerated-X server:

#> cd /usr/local/stow
#> stow -D --target=/usr XiG
#> cd ../packages
#> rm -rf XiG
#> rm /etc/Xaccel.ini
#> dpkg-divert --remove /usr/X11R6/lib/libGL.so.1.2
#> dpkg-divert --remove /usr/X11R6/lib/libGLU.so.1.3
#> ldconfig

⇐ table of contents | top ⇒


XFree86 4.2.1 Radeon Server

Lo and behold! The XFree86 4.2.1 server in the Debian “sarge” distribution incorporates a patch, which adds support for the ATI Mobility FireGL 7800 chip — albeit without AGP support. Under this server, glxgears runs here at 256 fps (13 fps in fullscreen mode) only. At least the wheels turn more or less smoothly. This server is, by the way, fast enough to watch DVDs.

Debian packages for the XFree86 4.2.1 Radeon server from “sarge”:

xserver-xfree86     (4.2.1-3)

Downloading and installing XFree86 4.2.1:

#> cd /usr/local/debian/dists/sarge/main/binary-i386
#>
#> wget http://ftp.de.debian.org/debian/pool/main/x/xfree86/xserver-xfree86_4.2.1-3_i386.deb
#>
#> cd /usr/local/debian
#> echo "xserver-xfree  optional  local" >> override.local.sarge
#>
#> dpkg-scanpackages dists/sarge/main/binary-i386/local override.local.sarge > \
> dists/sarge/main/binary-i386/Packages   
#> apt-get update
#> apt-get upgrade

Note: xserver-xfree86_4.2.1-3 depends on libc6_2.2.5-14.3, which we did already install while upgrading gcc.

/etc/X11/xdm/Xservers:

:0 local /usr/X11R6/bin/X :0 vt12 -layout Radeon -deferglyphs 16 -terminate

To configure the Radeon server, we just add one more server layout definition to /etc/X11/XF86Config-4:

Addition of a second server layout to /etc/X11/XF86Config-4:

Section "Monitor"
	Identifier	"TFT UXGA Monitor"
	DisplaySize     305 228
	Gamma           1.7
	Option		"DPMS"
EndSection

Section "Device"
        Identifier      "ATI Framebuffer"
        Driver          "fbdev"
        Option          "UseFBDev"              "true"
EndSection

Section "Device"
        Identifier      "ATI Radeon"
        Driver          "ati"
EndSection

Section "Screen"
        Identifier      "Framebuffer Screen"
        Device          "ATI Framebuffer"
        Monitor         "TFT UXGA Monitor"
        DefaultDepth    24
        SubSection "Display"
                Depth           24
                Modes           "1600x1200"
        EndSubSection
EndSection

Section "Screen"
        Identifier      "Radeon Screen"
        Device          "ATI Radeon"
        Monitor         "TFT UXGA Monitor"
        DefaultDepth    24
        SubSection "Display"
                Depth           24
                Modes           "1600x1200"
        EndSubSection
EndSection

Section "ServerLayout"
        Identifier      "Framebuffer"
        Screen          "Framebuffer Screen"
        InputDevice     "Internal Keyboard"
        InputDevice     "Trackpoint"
        InputDevice     "Mouse"
EndSection

Section "ServerLayout"
        Identifier      "Radeon"
        Screen          "Radeon Screen"
        InputDevice     "Internal Keyboard"
        InputDevice     "Trackpoint"
        InputDevice     "Mouse"
EndSection

Note: The Xsetup configuration tool from the XiG Accelerated Server suggests a gamma value of 2.432 (and a few other colour corrections) for our TFT monitor. Using some visual gamma correction tables and this nifty java-applet, we get on a somewhat lower gamma value of 2.2. Nevertheless, we settle for a value of 1.7 (or even less). Note also: The physical display size of 305 x 228 mm² results in resolution of 133 dpi.

⇐ table of contents | top ⇒


Laptop-Net

There exists a nifty Debian package called laptop-net, which allows the automagic detection of the IP address and subsequent reconfiguration of the system as a function of this IP address. Unfortunately, this package does not work as advertised. At least not here and now.

Update: Even the more recent versions of the laptop-net packagec continue to suck. Unfortunately, the package maintainer does not bother to answer emails, so we decided to roll our own variant and flush this crap here down the virtual toilet.

First of all, the package installation process overwrites important configuration files. Furthermore, Intel's ethernet driver e100 is not supported by one of the scripts in the package. So we better divert them, before we add our own modifications.

Diverting important laptop-net configuration files:

#> dpkg-divert --rename /etc/default/laptop-net
#> dpkg-divert --rename /etc/laptop-net/schemes
#> dpkg-divert --rename /usr/share/laptop-net/shared.sh
#> cp /etc/default/laptop-net.distrib /etc/default/laptop-net
#> cp /etc/laptop-net/schemes.distrib /etc/laptop-net/schemes
#> cp /usr/share/laptop-net/shared.sh.distrib /usr/share/laptop-net/shared.sh

Then we add support for the Intel e100 driver by editing /etc/default/laptop-net and /usr/share/laptop-net/shared.sh.

Addition of Intel e100 driver to /etc/default/laptop-net:

# MODULE_NAME="eepro100"
MODULE_NAME="e100"

Addition of Intel e100 driver to /usr/share/laptop-net/shared.sh:

        case "${MODULE_NAME}" in
#        3c59x | 8139too | au1000_eth | eepro100 | epic100 | fealnx | hamachi \
        3c59x | 8139too | au1000_eth | e100 | eepro100 | epic100 | fealnx | hamachi \

        case "${MODULE_NAME}" in
#        3c59x | eepro100 | epic100 | old_tulip | pcnet32 | rtl8139 | sis900 \
        3c59x | e100 | eepro100 | epic100 | old_tulip | pcnet32 | rtl8139 | sis900 \

Next, the automatic ARP detection of our IP address does not work in all cases. For this reason we have to puzzle together our own method of automagically determining our network.

We have hacked together a little script, which can do the automatic network detection by pinging the gateway for static interfaces and by analysing the responses of the DHCP client. Being based on a shell script, this method is rather slow. Having to wait for ping-timeouts, it is even slower. But it seems to work. It would still be a good idea to write a small C program for this job. To integrate it into the laptop-net package, we have to modify /usr/share/laptop-net/shared.sh.

Modification of /usr/share/laptop-net/shared.sh for ping-discovery:

# ARP_DISCOVERY=/usr/lib/laptop-net/arp-discovery
ARP_DISCOVERY=/usr/local/packages/laptop-net/ping-discovery

Shell script for ping-discovery:

#!/bin/sh
# /usr/local/packages/laptop-net/ping-discovery:

if [ -z "$1" ]; then
  echo "Usage: ping_discovery <interface > <ip-map>"
  exit 1
fi  

INTERFACE="$1"
IPMAPFILE="$2"
SCHEME_DIR=/var/lib/laptop-net/schemes

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

# Load available schemes from /etc/laptop-net/ip-map.

SCHEME=`grep -v -E "(^$|#)" ${IPMAPFILE} | awk '{print $1}'`

if [ -z "$SCHEME" ]; then
    echo "@NO-CHOICES@"
    exit 1
fi    

# Allow for extremely long negotation times with stoopid switches

sleep 30

# Test interface configuration: if already configured, return scheme; if
# unknown configuration, bring the interface down; if not configured, continue

IFTEST=`ifconfig | grep -A 1 "${INTERFACE}" | tail -1 | sed -e "s/:/ /" | awk '{print $3}'`

if [ -n "${IFTEST}" ]; then
  for s in ${SCHEME}; do
    IFACE=${SCHEME_DIR}/$s
    ADDRESS=`grep "address" ${IFACE} | awk '{print $2}'`
    if [ "${IFTEST}" = "${ADDRESS}" ]; then
      echo $s
      exit 0
    fi
  done
  ifconfig ${INTERFACE} down
fi  

#------------------------------------------------------------------------------
# Loop over all non-DHCP schemes, try to bring up the interface and ping the 
# gateway

for s in ${SCHEME}; do
    IFACE=${SCHEME_DIR}/$s
    DHCP=`grep "dhcp" $IFACE`
    if [ -z "$DHCP" ]; then
      ADDRESS=`grep "address" ${IFACE} | awk '{print $2}'`
      NETMASK=`grep "netmask" ${IFACE} | awk '{print $2}'`
      BROADCAST=`grep "broadcast" ${IFACE} | awk '{print $2}'`
      GATEWAY=`grep "gateway" ${IFACE} | awk '{print $2}'`
      ifconfig ${INTERFACE} ${ADDRESS} netmask ${NETMASK} broadcast ${BROADCAST} up
      ping -r -c 1 ${GATEWAY} &> /dev/null
      SUCCESS=$?
      ifconfig "${INTERFACE}" down
      if [ "${SUCCESS}" = 0 ]; then
        echo $s
        exit
      fi
    fi
done

#------------------------------------------------------------------------------
# Try to bring up the interface using DHCP (somewhat ugly since the DHCLIENT
# does not exit on failures but brings up the interface anyway, blech ...)

for s in ${SCHEME}; do
    IFACE=${SCHEME_DIR}/$s
    DHCP=`grep "dhcp" $IFACE`
    if [ -n "$DHCP" ]; then
      /sbin/dhclient-2.2.x -e ${INTERFACE} &gt; /tmp/DHCLIENT.log
      SUCCESS=`grep "DHCPACK" /tmp/DHCLIENT.log`
      kill `pidof dhclient-2.2.x`
      ifconfig "${INTERFACE}" down
      rm -f /tmp/DHCLIENT.log
      if [ -n "${SUCCESS}" ]; then
        echo $s
        exit
      fi
    fi
done    

echo "@NO-RESPONSES@"
exit 0

Note: We redefine the layout of the IP-to-SCHEME map file /etc/laptop-net/ip-map. Each line in this file contains now two entries: first the name of the scheme, and second the expected IP number under this scheme. If the network interface is configured via DHCP, only the name of the scheme is collected. In this case, the second entry with the IP number is not necessary.

Note also: We only need one single scheme for DHCP even if we use this for more than one network. That's what the different profiles are for.

/etc/laptop-net/ip-map:

# schemes for different static IP addresses

scheme1  www.xxx.yyy.zzz    = our expected IP address under scheme1
scheme2  WWW.XXX.YYY.ZZZ    = our expected IP address under scheme2

# one single scheme for DHCP

scheme3                       no IP number necessary

We also want to transfer the “control” of all network related boot scripts from the boot process rcS to the Laptop-Net daemon ifd — without confusing the Debian package management system, of course. To do so, we have to remove the symlinks from the /etc/rcN.d directories and install them in the /etc/laptop-net/profiles/XXXX/rc.d, where XXXX is one of home, work or local. Since the Debian boot-script manager update-rc.d will reinstall these links as long as it find the corresponding script in /etc/init.d, we have to divert these to a different location.

Diverting the boot script from init to ifd:

#!/bin/sh

mkdir /etc/laptop-net/init.d
PACKAGES="dns-clean fetchmail ippl lprng ntp ntpdate ppp scandetd ssh xinetd"
for p in $PACKAGES; do
  dpkg-divert --rename --divert /etc/laptop-net/init.d/$p /etc/init.d/$p
  update-rc.d $p remove
done

Now we go to the rc.d directories and create the new symlinks by hand.

Creating the new startup/shutdown symlinks (example):

#> cd /etc/laptop-net/profiles
#> mkdir -p work/rc.d home/rc.d xxx-default/rc.d
#> cd work/rc.d
#> ln -s ../../../init.d/ssh S20ssh
#> ln -s ../../../init.d/ssh K20ssh

Now we have a problem with ifd, the daemon which watches the status of our ethernet adapter. There seems to exist a race between the daemon itself and the termination of the link-change shell script, which is forked by this daemon. The offending lines are in the source file ifd.c, more precisely in the subroutine execute:

src/ifd.c:

static int
execute (const char * msg, const char * cmd)
{
  int ret;
  FILE * f;
  char line [256];
  const char * suffix = " 2>&1";
  unsigned int limit = ((sizeof (line)) - ((strlen (suffix)) + 1));
    
  syslog (LOG_INFO, "executing: '%s'", cmd);
  strncpy (line, cmd, limit);
  (line[limit]) = '\0';
  strcat (line, suffix);
  f = (popen (line, "r"));
  while (fgets (line, 255, f))
    {
      (line [(strlen (line)) - 1]) = '\0';
      syslog (LOG_INFO, "+ %s", line);
    }
  ret = (pclose (f));
  if (WIFEXITED (ret))
    {
      if (WEXITSTATUS (ret))
        syslog (LOG_INFO, "%s exited with status %d",
                msg, (WEXITSTATUS (ret)));
      return (WEXITSTATUS (ret));
    }
  else
    {
      syslog (LOG_INFO, "%s exited on signal %d",
              msg, (WTERMSIG (ret)));
      return (-1);
    }
}

The while loop ends as soon as fgets encounters an EOF condition. But since we are connected to stdout of the forked shell process, this means that the shell process is terminating at this point. By the time pclose is called it has terminated, so that pclose essentially waits on a no longer existing process, i.e. forever. The dead shell becomes a zombie process and ifd remains stalled until killed.

In order to fix this problem, we have hack the source code of ifd and replace the subroutine execute by:

src/ifd.c:

static int
execute (const char * msg, const char * cmd)
{
  syslog (LOG_INFO, "executing: '%s'", cmd);
  return system(cmd);
}

All in all, our installation of laptop-net is hideous and slow. But it works.

⇐ table of contents | top ⇒


PCMCIA-CS

Although we don't need to compile any kernel modules from the pcmcia-cs packge, we want to compile the corresponding tools. The reason herefore is simple: The pcmcia tools distributed in the binary package are not “trusting”, i.e. we can not change the pcmcia schemes as a normal user. To change this, we have to install the pcmcia-source package, unpack the tar-ball, reconfigure the kernel, configure the pcmcia package and finally compile and install the new package.

Debian package for PCMCIA sources:

pcmcia-sources

Building and installing the pcmcia-cs package:

#> cd /usr/src
#> tar xzf pcmcia-cs.tar.gz
#> cd kernel-source-2.4.19
#> make oldconfig; make dep
#> cd ../modules/pcmcia-cs
#> make config
#> cp config.* debian
#> debian/rules binary-cs
#> cd ..
#> mv pcmcia-cs_3.1.33-6_i386.deb /usr/local/debian/dists/woody/main/binary-i386/local
#> cd /usr/local/debian
#> echo "pcmcia-cs_3.1.33-6_i386.deb" >> override.local
#> dpkg-scanpackages dists/woody/main/binary-i386/local override.local > \
> dists/woody/main/binary-i386/Packages
#> apt-get update
#> apt-get install --reinstall pcmcia-cs

We also want to integrate our PCMCIA setup with the laptop-net infrastructure. We base our configuration on the presupposition that laptop-net is always up, running and watching the status of eth0. Furthermore, we assume that eth0 will always be associated with the internal ethernet adaptor, so that our ethernet PC-card will always show up as eth1. Lastly, we want that eth1 gets managed by laptop-net only in the case, when no network is attached to eth0.

To do so, we use a script /usr/local/packages/laptop-net/pcmcia, which we call from the PCMCIA network script /etc/pcmcia/network.opts.

/usr/local/packages/laptop-net/pcmcia:

#!/bin/sh

INTERFACE="eth0"
PROF_CHANGE=/usr/share/laptop-net/profile-change

IFTEST=`ifconfig | grep -A 1 "${INTERFACE}" | tail -1 | sed -e "s/:/ /" | awk '{print $3}'`

if [ -z "${IFTEST}" ]; then
  ${PROF_CHANGE} $*
fi
exit 0

Update of /etc/pcmcia/network.opts:

    # Extra stuff to do after setting up the interface
    start_fn() { /usr/local/packages/laptop-net/pcmcia $DEVICE; return; }
    # Extra stuff to do before shutting down the interface
    stop_fn() { /usr/local/packages/laptop-net/pcmcia $DEVICE down; return; }

⇐ table of contents | top ⇒


Sub-Pixel Font-Rendering

Sub-Pixel Font-Rendering is a Good Thing™. It's actually an old idea, whose time has finally come or will come really soon now on a LCD display near you. To triple the horizontal screen resolution for font rendering right now, we have to install XFree86 4.2.1 and then compile and install the new font configuration scheme fontconfig and update the X Render Extension together with libXft.

Debian Packages needed for compiling fontconfig:

libexpat1-dev
libfreetype6-dev

Compiling and installing fontconfig and Xft:

#> eval `build-i686`
#>
#> cd /usr/local/packages
#> mkdir -p fontconfig-2.0/local/src
#> cd fontconfig-2.0/local/src
#> wget http://fontconfig.org/release/fcpackage.2_0.tar.gz
#> tar xzf fcpackage.2_0.tar.gz
#>
#> cd fcpackage.2_0/fontconfig
#> ./configure --prefix=/usr/local/packages/fontconfig-2.0/X11R6
#> make
#> make install
#> cd /usr/local/stow
#> ln -s ../packages/fontconfig-2.0 .
#> stow -v --target=/usr fontconfig-2.0
#> 
#> cd /usr/local/packages/fontconfig-2.0/local/src/fcpackage.2_0/Xrender
#> xmkmf -a
#> make
#> dpkg-divert --rename /usr/X11R6/lib/libXrender.a
#> dpkg-divert --rename /usr/include/X11/extensions/Xrender.h
#> dpkg-divert --rename /usr/include/X11/extensions/render.h
#> dpkg-divert --rename /usr/include/X11/extensions/renderproto.h
#> make install
#>
#> cd ../Xft1
#> xmkmf -a
#> make
#> make install
#>
#> cd ../Xft
#> ./configure --prefix=/usr/local/packages/fontconfig-2.0/X11R6
#> make
#> dpkg-divert --rename /usr/include/X11/Xft/Xft.h
#> make install
#> cd /usr/local/stow
#> stow -v -D --target=/usr fontconfig-2.0
#> cd /usr/local/packages/fontconfig-2.0
#> mkdir -p lib/pkgconfig
#> ln -s X11R6/lib/pkgconfig/* lib/pkgconfig
#> rm -rf local/src/fcpackage.2_0
#> cd /usr/local/stow
#> stow -v --target=/usr fontconfig-2.0

Xrender and Xft1 can not be stowed and must be installed directly into the X11R6 tree. This makes removing these files a bit cumbersome.

Removing fontconfig-2.0:

#> cd /usr/local/stow
#> stow -v -D --target=/usr fontconfig-2.0
#> rm fontconfig-2.0
#> rm -rf /usr/local/packages/fontconfig-2.0
#> dpkg-divert --remove /usr/include/X11/Xft/Xft.h
#>
#> rm /usr/X11R6/lib/libXrender.so
#> rm /usr/X11R6/lib/libXrender.so.1.1
#> rm /usr/X11R6/lib/libXrender.a
#> rm /usr/include/X11/extensions/Xrender.h
#> rm /usr/include/X11/extensions/extutil.h
#> rm /usr/include/X11/extensions/region.h
#> rm /usr/include/X11/extensions/render.h
#> rm /usr/include/X11/extensions/renderproto.h
#> dpkg-divert --remove /usr/X11R6/lib/libXrender.a
#> dpkg-divert --remove /usr/include/X11/extensions/Xrender.h
#> dpkg-divert --remove /usr/include/X11/extensions/render.h
#> dpkg-divert --remove /usr/include/X11/extensions/renderproto.h
#> ldconfig
#>
#> rm /usr/X11R6/lib/libXft.so
#> rm /usr/X11R6/lib/libXft.so.1.2
#> ldconfig

Finally, we have to marry the new XFree86 font configuration fontconfig with the Debian font manager defoma. To this end we modify /etc/fonts/fonts.conf.

Modification of /etc/fonts/font.conf:

<!-- Font directory list configured on Sat Nov 16 01:41:41 CET 2002 -->

        <dir>/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType</dir>
        <dir>/var/lib/defoma/x-ttcidfont-conf.d/dirs/CID</dir>
        <dir>/usr/X11R6/lib/X11/fonts</dir>
        <dir>~/.fonts</dir>

⇐ table of contents | top ⇒


Xprint - the X11 print system

Setting up and configuring a printer under Linux can be adventuresome. Hooking up a postscript printer can become a nightmarish, especially if we want to print japanese postscript files on said printer. A few programs are clever enough to download japanese postscript fonts into the printer before they attempt to print. Most programs, however, assume that the printer has installed japanese postscript fonts — which is usually not the case outside of Japan.

A project, which attempts to remedy this situation is XPrint. This is essantially a X11 server, which does send its output to the printer instead of the screen. We want to use the development trunk release 008, since it supports TrueType fonts.

First we download the source tar-ball, which we extract into a separate directory for compilation. Compiling and installing is well described by the installation manual and is quite simple.

Downloading and Compiling Xprint:

#> cd /usr/local/packages
#> wget http://puck.informatik.med.uni-giessen.de/download/xprint_mozdev_org_source-2002-12-02-trunk.tar.gz
#> tar xzf xprint_mozdev_org_source-2002-12-02-trunk.tar.gz
#> cd xprint/src/xprint_main/xc/
#> make World 2>&1 | tee -a buildlog.log
#> cd packager/
#> make make_xprint_tarball
#> cd /usr/local/packages
#> rm -rf xprint
#> mkdir -p xprint/usr/local/src/xprint
#> mv /tmp/xprint_server_030118184734.tar.gz xprint/usr/local/src/xprint
#> mv xprint_mozdev_org_source-2002-12-02-trunk.tar.gz xprint/usr/local/src/xprint
#> cd xprint
#> tar xzf usr/local/packages/xxprint/xprint_server_030118184734.tar.gz
#> cd etc
#> mkdir -p laptop-net/init.d
#> mv init.d/xprint laptop-net/init.d
#> rmdir init.d
#> cd /usr/local/stow
#> ln -s ../packages/xprint .
#> stow -v --target=/ xprint

The number in the name of the tar-ball will depend of the exact building date. To use the Xprint server, we have to add two variables to the environment:

/etc/environment:

# xprint server

export XPSERVERLIST="`/etc/laptop-net/init.d/xprint get_xpserverlist`"
export XPRINTER="lp"

Finally, we set the necessary links in the laptop-net directories:

Creating the new startup/shutdown symlinks (example):

#> cd /etc/laptop-net/profiles
#> mkdir -p work/rc.d home/rc.d xxx-default/rc.d
#> cd work/rc.d
#> ln -s ../../../init.d/xprint S34xprint
#> ln -s ../../../init.d/xprint K04xprint

Integrating Xprint into laptop-net leaves us with the problem that we must ensure that the two environment variables are always and under all profiles well defined. To do so, we set up /dev/null as printing device for profiles without a real printer and start lprng and Xprint with this empty device. Furthermore, we wrap all Xprint aware programs (in our case Mozilla) in shell scripts, which set these two variables explicitly before starting the program.

Xprint constructs its font path not by consulting the XFree86 configuration file but by searching for fonts.dir files below the XPROJECTROOT directory. This is not quite what we want for two reasons: First, Xprint misses all fonts managed by defoma, second, it finds all fonts — even those, which we have explicitly exluded in our XFree86 configuration file. This behaviour can easily be corrected by editing the Xprint boot script.

Adapting /etc/laptop-net/init.d/xprint:

get_system_fontlist()
{
  case "$(uname -s)" in
  *SunOS*)
    ;;
  Linux)
    XF86CONFIG="/etc/X11/XF86Config-4"
    xfontpath=`grep "FontPath" $XF86CONFIG | egrep -v "^#" | sed 's/FontPath//' | tr "\"," " "`
    ( for xpath in $xfontpath; do
      echo $xpath | sed 's/:unscaled//'
      done ) | sort | uniq
    ;;
  *)
    ;;
esac
}

⇐ table of contents | top ⇒


Mozilla

One of the most important programs supporting sub-pixel font-rendering right now is The Beast, a.k.a. Mozilla. Unfortunately the precompiled binaries available at the Mozilla Homepage lack this feature, so we have to use the source and compile the thing ourselves. Fortunately, this has become quite easy.

First we use the Unix Build Configurator to configure The Beast. To compile for sub-pixel font-rendering, we have to enable Xft support. Depending on the actual configuration of Mozilla, we then have to install a few Debian packages.

Mozilla Configuration File ~/mozconfig:

# sh
# Build configuration script
#
# See http://www.mozilla.org/build/unix.html for build instructions.
#

# Options for 'configure' (same as command-line options).
ac_add_options --prefix=/usr/local/packages/mozilla-1.2b
ac_add_options --with-pthreads
ac_add_options --with-system-jpeg=/usr/lib
ac_add_options --with-system-zlib=/usr/lib
ac_add_options --with-system-png=/usr/lib
ac_add_options --with-system-mng=/usr/lib
ac_add_options --enable-default-toolkit=gtk
ac_add_options --enable-toolkit-gtk
ac_add_options --disable-mailnews
ac_add_options --enable-xft
ac_add_options --enable-xprint
ac_add_options --enable-crypto
ac_add_options --disable-accessibility
ac_add_options --disable-installer
ac_add_options --disable-debug
ac_add_options --disable-logging
ac_add_options --enable-strip
ac_add_options --enable-elf-dynstr-gc

Debian packages needed to compile Mozilla:

libjpeg62-dev
zlib1g-dev
libpng2-dev
libmng-dev
libgtk1.2-dev
libfreetype6-dev
pkg-config
libidl-dev

Furthermore, Mozilla wants a symlink (or alias) from libIDL-config-2 to libIDL-config. If all necessary packages are installed, compiling and installing Mozilla is quite simple.

Compiling Mozilla:

#> cd /usr/local/packages
#> wget ftp://sunsite.cnlab-switch.ch/mirror/mozilla/mozilla/releases/mozilla1.2b/src/mozilla-source-1.2b.tar.gz
#> tar xzf mozilla-source-1.2b.tar.gz
#> cd mozilla
#> cp ~/mozconfig .mozconfig
#> make -f client.mk build
#> make install
#> cd ..
#> rm -rf mozilla
#> ln -s mozilla-1.2b mozilla

We use a small shell script to set the MOZILLA_HOME environment variable and launch the actual Mozilla startup script.

Mozilla Startup-Script /usr/local/bin/mozilla:

#!/bin/sh

export XPSERVERLIST="`/etc/laptop-net/init.d/xprint get_xpserverlist`"
export XPRINTER="lp"

MOZILLA_HOME="/usr/local/software/mozilla"

set -e
# Check for DISPLAY
if [ -z $DISPLAY ]
then
    echo "No DISPLAY is set."
    exit 1
fi

if [ -x $MOZILLA_HOME/bin/mozilla ]; then
  exec $MOZILLA_HOME/bin/mozilla "$@"
else
  echo "$MOZILLA_HOME/bin/mozilla not found."
  exit 1
fi
exit 1

⇐ table of contents | top ⇒


tpb (ThinkPad Buttons)

tpb is a clever program, which analyses the content of the NVRAM to monitor the volume and brightness settings, thinklight and many things more. It also lets us attach a shell command to the <ThinkPad> key. To write the information to blend the status informations into the screen tpb uses xosd.

An antiquated version of xosd exists as a Debian package. The latest version has, however, a few interesting features, which make it worthwhile to compile and install it manually. tpb does not exist as an official Debian package (yet), but we could easily build one from the tar-ball. Since we want to modify the source code, we prefer to stow this package manually.

The reason for our modification is that tpb segfaults, if we try to use a non-existent font for displaying. tpb sets -*-lucidatypewriter-medium-r-normal-*-*-250-*-*-*-*-*-* as the default fall-back font. Neither is this font guaranteed to exist nor does tpb check its availability. We should therefore change the default font in cfg.h to 10x20.

If we stow tpb, we must either set an alias or write a shell script to teach tpb the location of its default configuration file, which in our case is /usr/local/etc/tpbrc.

Compiling and Installing xosd:

#> cd /usr/local/packages
#> mkdir -p xosd-2.0.1/src
#> cd xosd-2.0.1/src
#> wget http://www.ignavus.net/xosd-2.0.1.tar.gz
#> tar xzf xosd-2.0.1.tar.gz
#> cd xosd-2.0.1
#> configure --prefix=/usr/local/packages/xosd-2.0.1
#> make
#> make install
#> cd ..
#> rm -rf xosd-2.0.1
#> cd /usr/local/stow
#> ln -s ../packages/xosd-2.0.1 .
#> stow -v xosd-2.0.1

Moficiation of cfg.h:

/** #define DEFAULT_OSDFONT "-*-lucidatypewriter-medium-r-normal-*-*-250-*-*-*-*-*-*" **/
#define DEFAULT_OSDFONT "10x20"

Compiling and Installing tpb:

#> mknod /dev/nvram c 10 144
#> cd /usr/local/packages/
#> mkdir -p tpb-0.4.1/src
#> cd tpb-0.4.1/src
#> wget http://www.savannah.nongnu.org/download/tpb/tpb-0.4.1.tar.gz
#> tar xzf tpb-0.4.1.tar.gz
#> cd tpb-0.4.1
#> ./configure --prefix=/usr/local/packages/tpb-0.4.1
#> make
#> make install
#> cd ..
#> rm -rf tpb-0.4.1
#> cd ../bin
#> mv tpb tpb.bin
#> vi tpb
#> cd /usr/local/stow
#> ln -s ../packages/tpb-0.4.1 .
#> stow -v tpb-0.4.1

/usr/local/packages/tpb-0.4.1/bin/tpb:

#!/bin/sh

/usr/local/bin/tpb.bin --config=/usr/local/etc/tpbrc $@ &

⇐ table of contents | top ⇒


Intel Fortran Compiler

Since we use our machine for scientific number crunching, we need a decent Fortran compiler. The combo f2c plus fort77 is way too slow and g77 had a few numerical problems last time we checked.

For this reason we want to install the Intel Fortan Compiler ifc. And once more we are amazed how commercial products just fail to install without a pain in the ass. alien as well as rpm refuse to install the package, so we have to do it manually.

Compiling and Installing ifc:

#> cd /usr/local/packages
#>
#> mkdir -p ifc7-7.0/lib/ifc7/license
#> cp ~/l_for_38668925.lic ifc7-7.0/lib/ifc7/license
#> chmod +r ifc7-7.0/lib/ifc7/license
#> mkdir -p ifc7-7.0/doc/ifc7
#>
#> mkdir intel-install
#> cd intel-install
#> tar xzf ~/INTEL.TAR.GZ
#> alien -g intel-ifc7-7.0-64.i386.rpm
#> cd intel-ifc7-7.0.orig/opt/intel/compiler70/ia32
#> tar cf - . | (cd /usr/local/packages/ifc7-7.0; tar xf -)
#> cd ..
#> mv training docs
#> cd docs
#> tar cf - . | (cd /usr/local/packages/ifc7-7.0/doc/ifc7; tar xf -)
#> cd ..
#> tar cf - man | (cd /usr/local/packages/ifc7-7.0; tar xf -)
#> chown -R 0.0 *
#> cd doc/ifc
#> chmod -R -x *
#> find . -type d -exec chmod +x {} \;
#>
#> cd /usr/local/stow
#> ln -s ../ifc7-7.0 .
#> stow ifc7-7.0
#>
#> ldconfig
#>
#> rm -rf /usr/local/packages/intel-install

Now we have to edit the wrapper script, which is supposed to launch the compiler:

/usr/local/packages/ifc7-7.0/bin/ifc:

#!/bin/sh

INTEL_LICENSE_FILE=/usr/local/lib/ifc7/license;
export INTEL_LICENSE_FILE;

if [ -z LD_LIBRARY_PATH ]
then 
 LD_LIBRARY_PATH=/usr/local/lib
else
 LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
fi
export LD_LIBRARY_PATH

export -n IA32ROOT; unset IA32ROOT;

if [ $# != 0 ]
then
 exec -a "/usr/local/bin/ifc" /usr/local/bin/ifcbin "$@";
else
 exec -a "/usr/local/bin/ifc" /usr/local/bin/ifcbin;
fi

exit

⇐ table of contents | top ⇒


Linux WLAN

Our router wants us to connect via DHCP. So we have to install the corresponding Debian package first:

Debian packages for DHCP:

dhcp-client

The linux-wlan Project is developing a complete, standards based, wireless LAN system for Linux. The corresponding Debian package is available in the “unstable” (a.k.a. “sid”) distribution, which means that we have to compile it from source.

Unfortunately, the kernel modules refuse to compile and install automagically under “woody”, so we have to lend a helpin' hand and here and there. We have to edit the Debian rules file and then copy the resulting kernel modules.

Debian source packages for linux-wlan-ng:

wireless-tools_25-3
linux-wlan-ng_0.1.15-6

Installation of linux-wlan-ng:

#> dpkg-source -x wireless-tools_25-3.dsc
#> cd wireless-tools-25
#> dpkg-buildpackage
#> cd ..
#> mv wireless-tools_25-3_i386.deb /usr/local/debian/dists/woody/main/binary-i386
#> echo "wireless-tools optional local" >> /usr/local/debian/override.local.woody
#>
#> cd /usr/src/modules
#> dpkg-source -x linux-wlan-ng_0.1.15-6.dsc
#> cd linux-wlan-ng_0.1.15/
#> vi debian/rules                    # SEE BELOW
#> dpkg-buildpackage -d
#> cd ..
#> mv linux-wlan-ng_0.1.15-6_i386.deb /usr/local/debian/dists/woody/main/binary-i386
#> echo "linux-wlan-ng optional local" >> /usr/local/debian/override.local.woody
#>
#> cd ../linux
#> make-kpkg -rev Custom.1 modules_image
#> cd ..
#> mv linux-wlan-ng-modules-2.4.18_Custom.1+0.1.15-6_i386.deb /usr/local/debian/dists/woody/main/binary-i386/local/
#> echo "linux-wlan-ng-modules-2.4.18 optional local" >> /usr/local/debian/override.local.woody
#>
#> cd /usr/local/debian
#> dpkg-scanpackages dists/woody/main/binary-i386/local/ override.local.woody > dists/woody/main/binary-i386/Packages
#>
#> apt-get update
#> apt-get upgrade
#>
#> cd /usr/src/modules/linux-wlan-ng-0.1.15/debian/tmp
#> tar cf - lib | (cd /; tar xf -)
#> depmod -a

Edit of /usr/src/modules/linux-wlan-ng-0.1.15/debian/rules:

# line 29:
#  export DH_OPTIONS=-p$(PACKAGE) --mainpackage=$(PACKAGE)
   export DH_OPTIONS=-p$(PACKAGE)

# line 105:
# kdist_config:
  kdist_configure:

Note: In later versions of the linux-wlan-ng package (e.g. version 0.2.0-9) the automagic installation of the kernel modules is completely f...ed up. We have to do it manually:

Manual installation of the linux-wlan-ng modules:

#> cd /lib/modules/2.4.18/
#> mkdir net pcmcia usb
#> cp /usr/src/modules/linux-wlan-ng-0.2.0/src/p80211/p80211.o net
#> cp /usr/src/modules/linux-wlan-ng-0.2.0/src/prism2/driver/prism2_pci.o net
#> cp /usr/src/modules/linux-wlan-ng-0.2.0/src/prism2/driver/prism2_plx.o net
#> cp /usr/src/modules/linux-wlan-ng-0.2.0/src/prism2/driver/prism2_cs.o pcmcia
#> cp /usr/src/modules/linux-wlan-ng-0.2.0/src/prism2/driver/prism2_usb.o usb
#>
#> depmod -a

In the next step, we need to tell the system about our new network interface and the kernel modules. To do so, we edit /etc/network/interfaces and /etc/modutils/linux-wlan-ng and then update the modules list.

/etc/network/interfaces:

auto lo

iface lo inet loopback

iface wlan0 inet dhcp
      wireless_essid <SSID here>
      wireless_mode managed
      wireless_nick <insert name here>

/etc/modutils/linux-wlan-ng:

alias wlan0 prism2_pci

Updating the modules list:

#> update-modules

If everything is okay, the wlan0 interface should now be brought up if we type ifup wlan0 and receive some IP address from the router in the 192.168.123.0 subnet of our WLAN.

This simple WLAN setup is then expanded and integrated into our nifty network-profile handling mechanism.

Special Case: The USR-2410 PC Card

To support this card by the linux-wlan-ng drivers, we have to edit some configuration files and roll our own scripts. First, we have to uncomment the appropriate device definitions in /etc/pcmcia/wlan-ng.conf, otherwise the standard kernel drivers will get loaded.

/etc/pcmcia/wlan-ng.conf:

card "Intersil PRISM2 Reference Design 11Mb/s 802.11b WLAN Card"
   version "INTERSIL", "HFA384x/IEEE"
   bind "prism2_cs"

card "Intersil PRISM2 Reference Design 11Mb/s WLAN Card"
   manfid 0x0156, 0x0002
   bind "prism2_cs"

In the next step, we disable the mass of half-integrated half-messed-up scripts to handle the PC Card automagically. This is done by diverting the original wlan-ng script and the recplacing it by an empty script:

Diverting /etc/pcmcia/wlan-ng:

#> dpkg-divert --rename /etc/pcmcia/wlan-ng

New /etc/pcmcia/wlan-ng:

#!/bin/sh
exit

The next problem is that the standard WLAN tools called by ifup don't handle the WEP encryption for the linux-wlang-ng drivers correctly. We have to circumvent this by resticting the interface definition in /etc/network/interfaces to the bare minimum and then use our won script to setup the card:

New entry in /etc/pcmcia/wlan-ng:

iface wlan0-pccard inet dhcp

/usr/local/bin/wlan0:

#!/bin/sh

prog=`basename $0`
test "X$SUPERCMD" = "X$prog" || exec /usr/bin/super $prog ${1+"$@"}

PATH="/bin:/usr/bin/:usr/local/bin:/sbin:/usr/sbin"
ADDRESS=""

SCHEMEFILE=/var/state/network/scheme.wlan0
DEVICE=wlan0

touch $SCHEMEFILE

. /etc/wlan/shared

case "$1" in
     load)
          modprobe wlan0
          ;;
     unload)
          modprobe -r wlan0
          ;;
     up|start)
          echo "wlan0: start"
          if is_true $WLAN_DOWNLOAD; then
            wlan_download $DEVICE
          fi
          wlan_enable $DEVICE
          wlan_source_config $DEVICE
          wlan_user_mibs $DEVICE
          wlan_wep $DEVICE
          if is_true $IS_ADHOC ; then   
            wlan_adhoc $DEVICE
          else
            wlan_infra $DEVICE
          fi
          ifup wlan0 2> /dev/null
          ;;
     down|stop)
          echo "wlan0: down"
          wlan_disable $DEVICE
          ifdown wlan0 2> /dev/null
          rmmod -a; rmmod -a
          ;;
     restart)
          echo "wlan0: restart"
          ifdown wlan0 2> /dev/null
          sleep 1
          ifup wlan0 2> /dev/null
          ;;
     scheme)
          if [ -z "$2" ]; then
            cat $SCHEMEFILE | sed "s/-/ /" | awk '{print $2}'
          else
            echo "eth0-$" > $SCHEMEFILE
          fi
          ;;
     *)
      SCHEME=`cat $SCHEMEFILE | sed "s/-/ /" | awk '{print $2}'`
      SCHEMES=`grep iface /etc/network/interfaces | grep wlan0 | sed "s/-/ /" | awk '{
printf "%s ", $3}'`
      echo "Usage: wlan0 [up|start|down|stop|restart|scheme [xyz]]"
      echo "where xyz is one of:   $SCHEMES"
      echo "Current scheme is:     $SCHEME"
      ;;
esac

This script includes the standard linux-wlan-ng configuration files in /etc/wlan. We set the SSID of our access point in /etc/wlan/wlan.conf:

/etc/wlan/wlan.conf:

SSID_wlan0="myssid"

Then we copy the default configuration file /etc/wlan/wlancfg-DEFAULT to /etc/wlancfg-myssid and edit it to represent our detailed setup:

New /etc/wlan/wlancfg-myssid:

#=======USER MIB SETTINGS=============================
# You can add the assignments for various MIB items
#  of your choosing to this variable, separated by 
#  whitespace.  The wlan-ng script will then set each one.
# Just uncomment the variable and set the assignments 
#  the way you want them.

#USER_MIBS="p2CnfRoamingMode=1 p2CnfShortPreamble=mixed"

#=======WEP===========================================
# [Dis/En]able WEP.  Settings only matter if PrivacyInvoked is true
lnxreq_hostWEPEncrypt=true      # true|false
lnxreq_hostWEPDecrypt=true      # true|false
dot11PrivacyInvoked=true        # true|false
dot11WEPDefaultKeyID=0          # 0|1|2|3
dot11ExcludeUnencrypted=true    # true|false, in AP this means WEP is required.

# If PRIV_GENSTR is not empty, use PRIV_GENTSTR to generate 
#  keys (just a convenience)
PRIV_GENERATOR=/sbin/nwepgen    # nwepgen, Neesus compatible
PRIV_KEY128=false               # keylength to generate
PRIV_GENSTR=""

# or set them explicitly.  Set genstr or keys, not both.
dot11WEPDefaultKey0=01:02:03:04:05:06:07:08:09:0A:0B:0C:0D
dot11WEPDefaultKey1=11:12:13:14:15:16:17:18:19:1A:1B:1C:1D
dot11WEPDefaultKey2=21:22:23:24:25:26:27:28:29:2A:2B:2C:2D
dot11WEPDefaultKey3=01:32:33:34:35:36:37:38:39:3A:3B:3C:3D

#=======SELECT STATION MODE===================
IS_ADHOC=n                      # y|n, y - adhoc, n - infrastructure

#======= INFRASTRUCTURE STATION  ===================
# What kind of authentication?
AuthType="opensystem"           # opensystem | sharedkey (requires WEP)

#======= ADHOC STATION ============================
BCNINT=100                      # Beacon interval (in Kus)
CHANNEL=6                       # DS channel for BSS (1-14, depends 
                                #   on regulatory domain)
BASICRATES="2 4"                # Rates for mgmt&ctl frames (in 500Kb/s)
OPRATES="2 4 11 22"             # Supported rates in BSS (in 500Kb/s)

After inserting the card nothing happens. We have to start and stop the interface manually by issuing the commands wlan0 up and wlan0 down, respectively.

⇐ table of contents | top ⇒


Cisco VPN Client

There exists a piece of software called vpnclient, which let's us establish a secure, end-to-end encrypted tunnel to any Cisco central site remote access VPN product. This piece of software does even exist for Linux. Of course it does not work out of the box (at least not our version 3.7.2).

After unpacking the tar-ball, we have a look at the file interceptor.c, more precisely at the function supported_device. For some unknown reason, only the devices eth0 to eth9 and ppp0 to ppp9 are assumed to be valid networking devices. wlan0 is not mentioned at all.

To remedy the situation, we replace the provided function with our own:

supported_device in interceptor.c:

static int inline supported_device(struct device* dev)
{
    if(!dev->name) return 0;
    if(!strncmp(dev->name,"eth",3) && (dev->name[3]>='0' && dev->name[3]<='9'))
       return 1;
    if(!strncmp(dev->name,"ppp",3) && (dev->name[3]>='0' && dev->name[3]<='9'))
       return 1;
    if(ippp_dev(dev)) {
       isdn_net_local *lp = (isdn_net_local *) dev->priv;
       if(lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) return 1;
    }
    if(!strncmp(dev->name,"wlan",4) && (dev->name[4]>='0' && dev->name[4]<='9'))
       return 1;
    return 0;
}

In contrast to what the documentation claims, we don't need to load the provided kernel module at boot time. Our kernel is compiled to load its modules automagically at need. We just have to let it know, which module should be loaded:

/etc/modutils/vpn:

# Cisco VPN
alias cipsec0 cisco_ipsec

Now we update the modules with update-modules and are all set. We don't need the provided boot script /etc/init.d/vpnclient_init at all.

Later we integrate the VPN tunnel into our own network profile management.

⇐ table of contents | top ⇒


CD Recording as non-root User

Trying to burn CD-Rs as non-root user can be a tiring adventure, since the documentation of cdrecord does not really reflect the actual setup under Debian and is no longer entirely up to date. Furthermore, most of the tips and tricks divulged in the various mailing lists did not really impress by their insights.

To make a long story short, the probably best way to set things up is by using the super command. This makes sure that cdrecord is run with the real UID 0 and avoids all kind of hassles, among them the following error message:

cdrecord error message:

cdrecord.mmap: Operation not permitted. WARNING: Cannot set RR-scheduler
cdrecord.mmap: Permission denied. WARNING: Cannot set priority using setpriority().
cdrecord.mmap: WARNING: This causes a high risk for buffer underruns.

To do so, we write a small shell script named cdrecord, put it in /usr/local/bin and set execute permissions for all and everybody. Since the original cdrecord in /usr/bin does not have execute permissions for everybody, our version in /usr/local/bin will automagically executed, if a non-root user not in the group cdrom types cdrecord at the command prompt.

/usr/local/bin/cdrecord:

#!/bin/sh

prog=`basename $0`
test "X$SUPERCMD" = "X$prog" || exec /usr/bin/super $prog ${1+"$@"}

/usr/bin/cdrecord $@

The corresponding entry in /etc/super.tab reads:

/etc/super.tab:

cdrecord   /usr/local/bin/cdrecord uid=root info="burn CD-R" \
	   <registered user here>

⇐ table of contents | top ⇒


External Firewire Hard Disk

Although the 2.4 kernel series does not yet support hotplugging of SCSI and IEEE 1394 devices, we can easily configure for a simple manual setup. We make use of two scripts, namely rescan-scsi-bus.sh available from the IEEE 1394 For Linux project web pages and a homegrown helper script, to load the kernel necessary modules and scan for new SCSI devices:

/usr/local/bin/firewire:

#!/bin/sh

prog=`basename $0`
test "X$SUPERCMD" = "X$prog" || exec /usr/bin/super $prog ${1+"$@"}

PATH="/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin"
ADDRESS=""

case "$1" in
   up|start)
     modprobe ohci1394 && modprobe sbp2 && modprobe sd_mod
     sleep 1
     rescan-scsi-bus
     ;;
   down|stop)
     modprobe -r ohci1394 && modprobe -r sbp2 && modprobe -r sd_mod
     sleep 1
     rescan-scsi-bus -r
     ;;
   restart)
     rescan-scsi-bus -r
     sleep 1
     rescan-scsi-bus
     ;;
   *)
     echo "Usage: firewire [up|start|down|stop|restart]"
     ;;
esac

Note: We have renamed rescan-scsi-bus.sh into rescan-scsi-bus.

As before, we register our helper script with the super framework by adding the following lines to /etc/super.tab:

/etc/super.tab:

firewire     /usr/local/bin/firewire uid=root info="start/stop IEEE 1394" \
             <registered user here>
            

After physically plugging in the hard disk and launching the Firewire HD support by issuing the command firewire start, the disk shows up as /dev/sda and can be accessed as any other SCSI disk.

⇐ table of contents | previous section | next section | top ⇒