Freitag, 16. Dezember 2011

Compile ucspi-tcp-0.88 on Red Hat Enterprise Linux Client release 5.5 (Tikanga)

Compiling ucspi-tcp version 0.88 on Red Hat ES 5.5 fails with the following error:

./load tcpserver rules.o remoteinfo.o timeoutconn.o cdb.a \
        dns.a time.a unix.a byte.a  `cat socket.lib`
/usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference in tcpserver.o
/lib/libc.so.6: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [tcpserver] Error 1

The problem is the errno definition in error.h. The problem can be fixed with the following patch:

--- ucspi-tcp-0.88/error.h      2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.patched/error.h      2011-12-16 09:29:15.000000000 +0100
@@ -1,7 +1,8 @@
 #ifndef ERROR_H
 #define ERROR_H

-extern int errno;
+/* extern int errno; */
+#include 

 extern int error_intr;
 extern int error_nomem;

Mittwoch, 30. November 2011

Reading multiple return values with Bashs read function

It is quite easy to read a single return value of a sub process with Bash:

DATE=$(date)
echo $DATE
This command spawns a new process and stores the date and displays it. This is easy.

It becomes complicated if one needs the day and month in two different variables. Bashs standard function to parse input is read. So one could think this might be a possible way:

date | read DAY MONTH REST
echo $DAY $MONTH
But the above code prints only an empty line. The reason is that the pipe creates a new scope. An equivalent syntax for the above read is this:
date | (
    read DAY MONTH REST
)
echo $MONTH $DAY
Now it is obvious why the echo does not print anything. The variables are not valid any more when they get displayed, because the new scope has already been closed. One possible solution is to put the echo into the scope of the sub shell:
date | (
    read DAY MONTH REST
    echo $MONTH $DAY
)
Now the month and day is correctly displayed. But this solution has a major drawback. The standard input in the sub shell is the standard output of the date command and the original standard input of the surrounding shell gets shadowed and is not available any more in the sub shell.

The solution for this problem is: process substitution. The above command could be written this way using a process substitution:

(
    read DAY MONTH REST
    echo $MONTH $DAY
) < <(date)
The expression <(date) returns a file descriptor and the output of that file descriptor is redirected to the read block. You can try it with
echo <(date)
Which prints the file descriptor and
cat < <(date)
which prints the date. But this alone does not help much, because the read is still executed in a sub shell and the variables created by read are in a scope which does not have access to the original standard input. But by using a process substitutions it is possible to avoid the complete sub shell by redirecting the output of date directly into the read.

Normally read reads only from standard input but it is possible to specify a file descriptor by the use of the -u option. Unfortunately Bash uses a different syntax for the file descriptor. The process substitution prefixes the actual file descriptor number with /dev/fd/ while read expects the plain number. But the prefix can be stripped with Bashs parameter expansion functions. The ## operator matches the longest prefix and removes it:

FD=<(date)
echo $FD
echo ${FD##*/}

Combining all this in one line makes it possible to read more than one return value without introducing a new scope and without loosing the current standard input:

FD=<(date) read -u ${FD##*/} DAY MONTH REST
echo $MONTH $DAY

Freitag, 7. Oktober 2011

Bash Promt in Fett

Die folgende Definition der PS1-Variable führt dazu, dass sowohl der Bash-Promt fett gedruckt wird als auch der Titel des Fensters aktualisiert wird.

export PS1='\[\e]0;\u@\h: \w\a\e[1m\]\u@\h:\w\$\[\e[0m\] '

Das ist nützlich, um schnell die Zeile mit der letzten Eingabe erkennen zu können. Andernfalls verschwindet die letzte Eingabe leicht in der Ausgabe der vorherigen Befehle.

Samstag, 10. September 2011

Dateien löschen unter Windows

Nach langer Suche habe ich es endlich geschafft, unter Windows Dateien zu löschen.

Unter Unix tippt man einfach "rm -rf müll" und der Müll wird von der Platte entfernt.

Unter Windows ist diese denkbar einfache Aufgabe denkbar kompliziert. Man könnte auf die Idee kommen, das ein einfaches Drücken der Del-Taste im Explorer die Lösung sein könnte: weit gefehlt. Selbst Administratoren können nicht problemlos Dateien löschen. Beispielsweise ist es in bestimmten Situationen notwendig, erst den Besitz von Dateien zu übernehmen, bevor man sie löschen kann. Im Explorer kann das Löschen von Profilen eine Angelegenheit werden, für die man sich ruhig mal eine Auszeit von zwei Wochen gönnen kann. Ist eben alles viel einfacher unter Windows.

Wenn einem dann unter Windows wieder einfällt, dass es ja auch sowas wie eine Kommandozeile gab, ist einem nicht wirklich geholfen. Weder der Versuch mit "del /s /f" noch "rmdir /s /q" führt dazu, dass alle Daten problemlos gelöscht werden.

Aber wenn man lange genug sucht, findet man die Lösung. Man muss ein leeres Verzeichnis erstellen und dieses mit dem Befehl "robocopy" in das zu löschende Verzeichnis spiegeln. Dadurch entstehen zwei leere Verzeichnisse, die einfach mit "rmdir" gelöscht werden können. Das geht dann aber auch wieder im Explorer.
mkdir nix
robocopy nix müll /mir /sec
rmdir nix
rmdir müll
Ist doch einfacher als "rm -rf" oder?

Montag, 28. Februar 2011

Das fängt ja gut an

Nachdem wir den Service von Versatal zu hassen gelernt haben und Alice auch nicht wirklich überzeugen konnte, lag die Idee nahe, es mal wieder bei der Telekom zu versuchen. Morgen fängt der Vertrag an und weit und breit kein Router in Sicht. Beim Versuch auf das Service-Center zuzugreifen dann sowas:
Tuess bis demnächst mal, wenn ich wieder Internet habe...

Sonntag, 27. Februar 2011

Verbindungsproblem mit Apple Wireless Keyboard

Seit einiger Zeit plagte mich folgendes Problem bei der Benutzung des Apple Wireless Keyboards unter Debian Lenny und neuerdings Squeeze: nach dem Boot des Systems funktionierte die Tastatur nicht. Wenn man aber die Bluetooth-Verbindung zur Tastatur trennt und neu herstellt, funktionierte die Tastatur problemlos. Das Problem äußerte sich in der folgenden Kernel-Fehlermeldung:
apple 0005:05AC:023A.0003: parse failed
apple: probe of 0005:05AC:023A.0003 failed with error -14
Der Grund für das Problem ist, dass das Kernel-Modul hid_apple beim Boot nicht geladen wird. Man kann das Problem beheben, indem man das Modul in /etc/modules einträgt und danach das Boot-Image anpasst mit dem Befehl:
update-initramfs -u
Danach arbeitet die Tastatur wieder einwandfrei.

Mittwoch, 19. Januar 2011

Die Feststelltaste (Caps Lock) zu einer Steuerungstaste (Ctrl) machen

Mit der Version 4 hat sich das Verhalten von VirtualBox unter Linux beim Sender von Tasten geändert. Bislang konnte man über die Konfiguration des X-Servers die CapsLock-Taste zu einer Ctrl-Taste machen. Als 10-Finger-Schreiber ist das meine Standardkonfiguration, da es mir fast nicht möglich ist, mit dem kleinen Finger die Ctrl-Taste am unteren Ende der Tastatur zu erreichen. Eine Ctrl-Taste neben dem A ist dagegen sehr angenehm zu erreichen.


Diese Konfiguration wurde bislang an eine virtuelle Maschine weitergegeben. Dadurch war es ohne weitere Konfiguration möglich dieses Verhalten auch unter Windows zu nutzen. Mit der Version 4 geht das aber nicht mehr. Jetzt erkennt VirtualBox die Konfiguration des Hosts und neutralisiert eine abweichende Konfiguration des Tastatur-Layouts. Dadurch ist es notwendig in jedem Gast das Mapping von CapsLock auf Ctrl erneut zu konfigurieren.

Unter Windows XP muss man dafür eine REG-Datei mit folgendem Inhalt anlegen:

REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00

Die Datei muss in die Registry importiert werden und danach muss das System neu gebootet werden. Danach hat man auch im Windows-Gast neben dem A eine Ctrl-Taste.