Software aus Quelltext installieren

Zuerst soll LibreSSL direkt aus dem Quellcode gebaut werden, danach ein ‚sudo‘-Ersatz namens ‚doas‘.

Bei LibreSSL kommt „stow“ als Installer-Hilfswerkzeug zum Einsatz, was anstelle von harten Kopieraktionen nur entstrechende Symlinks erzeugt, die sich später wieder leicht entfernen lassen.

LibreSSL kompilieren und installieren

Siehe dazu auch:

Erforderliche Debian-Pakete

Es werden in Voraussetzung einige Pakete benötigt. Das sind zumindestens diese:

root@de:~ $ apt-get install make automake autoconf git libtool patch perl stow

Bereitstellen der Quellen

Das Herunterladen und Entpacken führen wir als einfacher User durch:

user@de:~ $ wget http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-3.2.2.tar.gz
user@de:~ $ tar xf libressl-3.2.2.tar.gz
user@de:~ $ cd libressl-3.2.2/
user@de:~/libressl-3.2.2 $

Konfiguration und Software bauen

Diese beiden Schritte erfolgen ebenfalls mit einfachem User-Account, sie sehen prinzipiell so aus:

  • Konfiguration: ./configure --prefix=/path/to/dir

  • Software bauen: make

user@de:~/libressl-3.2.2 $ ./configure --help | grep enable
--disable-option-checking  ignore unrecognized --enable/--with options
--disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
--enable-silent-rules   less verbose build output (undo: "make V=1")
--enable-dependency-tracking
--enable-shared[=PKGS]  build shared libraries [default=yes]
--enable-static[=PKGS]  build static libraries [default=yes]
--enable-fast-install[=PKGS]
--enable-nc             Enable installing TLS-enabled nc(1)
--enable-windows-ssp    Enable building the stack smashing protection on
--enable-extratests     Enable extra tests that may be unreliable on some
--disable-tests         Disable tests [default=enabled]
user@de:~/libressl-3.2.2 $
user@de:~/libressl-3.2.2 $
user@de:~/libressl-3.2.2 $ ./configure --prefix=/usr/local/stow/libressl-3.2.2 --enable-nc

   (gekürzt)

config.status: creating libtls.pc
config.status: creating openssl.pc
config.status: executing depfiles commands
config.status: executing libtool commands
user@de:~/libressl-3.2.2 $ echo $?
0
user@de:~/libressl-3.2.2 $ # Die Option '-j2' lässt zu, dass 2 CPU-Cores für das Bauen herangezogen werden können:
user@de:~/libressl-3.2.2 $ make -j2

   (gekürzt)

CC       x509.o
CC       certhash.o

   (gekürzt)

make[1]: Für das Ziel „all-am“ ist nichts zu tun.
make[1]: Verzeichnis „/root/libressl-3.2.2“ wird verlassen
user@de:~/libressl-3.2.2# echo $?
0
user@de:~/libressl-3.2.2 $

Software an Ort und Stelle installieren

Im dritten Schritt wird mit make install die Software ins Zielverzeichnis kopiert, welches wir im Schritt 1 mittels des configure-Skriptes samt Präfix bereits spezifiziert haben. Weil ein Nutzer unter /usr keine Schreibrechte hat, muss dies mit root-Rechten geschehen:

user@de:~/libressl-3.2.2 $ ## Das übliche Minus-Zeichen weglassen, damit wir im aktuellen Working Diretory bleiben:
user@de:~/libressl-3.2.2 $ /bin/su
Password:
root@ubuntu:/home/tux/libressl-3.2.2# make install

   (gekürzt)

make[2]: Verzeichnis „/root/libressl-3.2.2“ wird betreten
make[2]: Für das Ziel „install-exec-am“ ist nichts zu tun.
/usr/bin/mkdir -p '/usr/src/stow/libressl-3.2.2/lib/pkgconfig'
/usr/bin/install -c -m 644 libcrypto.pc libssl.pc libtls.pc openssl.pc '/usr/src/stow/libressl-3.2.2/lib/pkgconfig'
make[2]: Verzeichnis „/root/libressl-3.2.2“ wird verlassen
make[1]: Verzeichnis „/root/libressl-3.2.2“ wird verlassen
root@ubuntu:/home/tux//libressl-3.2.2#

Verlinkung mittels stow

Fehlt nur noch das Verlinken mit Hilfe des oben bereits mitinstallierten Tools:

root@ubuntu:/home/tux//libressl-3.2.2# cd /usr/local/stow/
root@ubuntu:/usr/local/stow#
root@ubuntu:/usr/local/stow#
root@ubuntu:/usr/local/stow# stow -v libressl-3.2.2/
LINK: lib/libcrypto.so => ../stow/libressl-3.2.2/lib/libcrypto.so
LINK: lib/libssl.so => ../stow/libressl-3.2.2/lib/libssl.so
LINK: lib/libtls.so => ../stow/libressl-3.2.2/lib/libtls.so
LINK: lib/libcrypto.so.46.0.1 => ../stow/libressl-3.2.2/lib/libcrypto.so.46.0.1
LINK: lib/libssl.so.48 => ../stow/libressl-3.2.2/lib/libssl.so.48
LINK: lib/libtls.a => ../stow/libressl-3.2.2/lib/libtls.a
LINK: lib/libtls.so.20 => ../stow/libressl-3.2.2/lib/libtls.so.20
LINK: lib/libcrypto.a => ../stow/libressl-3.2.2/lib/libcrypto.a
LINK: lib/libcrypto.so.46 => ../stow/libressl-3.2.2/lib/libcrypto.so.46
LINK: lib/libtls.so.20.0.1 => ../stow/libressl-3.2.2/lib/libtls.so.20.0.1
LINK: lib/libssl.la => ../stow/libressl-3.2.2/lib/libssl.la
LINK: lib/libcrypto.la => ../stow/libressl-3.2.2/lib/libcrypto.la
LINK: lib/pkgconfig => ../stow/libressl-3.2.2/lib/pkgconfig
LINK: lib/libssl.a => ../stow/libressl-3.2.2/lib/libssl.a
LINK: lib/libtls.la => ../stow/libressl-3.2.2/lib/libtls.la
LINK: lib/libssl.so.48.0.1 => ../stow/libressl-3.2.2/lib/libssl.so.48.0.1
LINK: etc/ssl => ../stow/libressl-3.2.2/etc/ssl
LINK: share/man/man3 => ../../stow/libressl-3.2.2/share/man/man3
LINK: share/man/man1/nc.1 => ../../../stow/libressl-3.2.2/share/man/man1/nc.1
LINK: share/man/man1/openssl.1 => ../../../stow/libressl-3.2.2/share/man/man1/openssl.1
LINK: share/man/man8 => ../../stow/libressl-3.2.2/share/man/man8
LINK: share/man/man5/x509v3.cnf.5 => ../../../stow/libressl-3.2.2/share/man/man5/x509v3.cnf.5
LINK: share/man/man5/openssl.cnf.5 => ../../../stow/libressl-3.2.2/share/man/man5/openssl.cnf.5
LINK: include/tls.h => ../stow/libressl-3.2.2/include/tls.h
LINK: include/openssl => ../stow/libressl-3.2.2/include/openssl
LINK: bin/nc => ../stow/libressl-3.2.2/bin/nc
LINK: bin/ocspcheck => ../stow/libressl-3.2.2/bin/ocspcheck
LINK: bin/openssl => ../stow/libressl-3.2.2/bin/openssl
root@ubuntu:/usr/local/stow#
root@ubuntu:/usr/local/stow# hash -r
root@ubuntu:/usr/local/stow#
root@ubuntu:/usr/local/stow# openssl version
LibreSSL 3.2.2
root@ubuntu:/usr/local/stow#
root@ubuntu:/usr/local/stow# /usr/bin/openssl version
OpenSSL 1.1.1f  31 Mar 2020
root@ubuntu:/usr/local/stow#

Zu „stow“ siehe auch: https://www.rosehosting.com/blog/how-to-easily-remove-packages-installed-from-source-in-linux/

Standalone-Anwendung: Dateiverschlüsselung

Nach http://www.herongyang.com/Blowfish/OpenSSL-bf-ecb-Blowfish-Ciphers.html ist das eine ziemlich einfache Sache:

my@bash $ ## Am besten gleich anstelle von '-bf' die voll ausgeschriebene Variante '-blowfish' benutzen:
my@bash $ openssl enc -blowfish <<< "Hallo Welt und Universum..." > datei.ciffre
enter bf-cbc encryption password:
Verifying - enter bf-cbc encryption password:
my@bash $
my@bash $
my@bash $ ## Die vollständige Variante mit '-blowfish' ist beim Dechiffrieren nämlich erforderlich:
my@bash $ openssl enc -d -blowfish -in datei.ciffre
enter bf-cbc decryption password:
Hallo Welt und Universum...
my@bash $

DoAs kompilieren und installieren

Ziel ist, das sehr umfangreiche und komplexe und damit fehleranfällige ‚sudo‘ durch ‚doas‘ zu ersetzen.

=> https://linuxnews.de/2020/10/linux-rechtemanagement-sudo-durch-doas-ersetzen/

Debian-Pakete, Downloaden der Quellen

Zum Kompilieren benötigte Softwarepakete installieren:

my@bash $ apt-get install git build-essential make bison flex libpam0g-dev

Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.
Statusinformationen werden eingelesen.... Fertig
git ist schon die neueste Version (1:2.25.1-1ubuntu3).
make ist schon die neueste Version (4.2.1-1.2).
Die folgenden Pakete wurden automatisch installiert und werden nicht mehr benötigt:
  libfprint-2-tod1 libllvm9
Verwenden Sie »apt autoremove«, um sie zu entfernen.
Die folgenden zusätzlichen Pakete werden installiert:
  dpkg-dev fakeroot g++ g++-9 libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl libfakeroot libfl-dev
  libfl2 libstdc++-9-dev
Vorgeschlagene Pakete:
  bison-doc debian-keyring flex-doc g++-multilib g++-9-multilib gcc-9-doc libstdc++-9-doc
Die folgenden NEUEN Pakete werden installiert:
  bison build-essential dpkg-dev fakeroot flex g++ g++-9 libalgorithm-diff-perl libalgorithm-diff-xs-perl
  libalgorithm-merge-perl libfakeroot libfl-dev libfl2 libpam0g-dev libstdc++-9-dev
0 aktualisiert, 15 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
Es müssen 12,1 MB an Archiven heruntergeladen werden.
Nach dieser Operation werden 53,0 MB Plattenplatz zusätzlich benutzt.
Möchten Sie fortfahren? [J/n]
libalgorithm-merge-perl (0.08-3) wird eingerichtet ...
libfl-dev:amd64 (2.6.4-6.2) wird eingerichtet ...
Trigger für libc-bin (2.31-0ubuntu9.1) werden verarbeitet ...
Trigger für man-db (2.9.1-1) werden verarbeitet ...
Trigger für install-info (6.7.0.dfsg.2-5) werden verarbeitet ...
my@bash $
my@bash $
my@bash $ exit
Abgemeldet
tux@ubu:~/Downloads$

Die Quellen beziehen wird diesmal aus einem GIT-Repository:

tux@ubu:~/Downloads$ git clone https://github.com/slicer69/doas.git
Klone nach 'doas' ...
remote: Enumerating objects: 123, done.
remote: Counting objects: 100% (123/123), done.
remote: Compressing objects: 100% (98/98), done.
remote: Total 372 (delta 64), reused 60 (delta 24), pack-reused 249
Empfange Objekte: 100% (372/372), 133.85 KiB | 801.00 KiB/s, Fertig.
Löse Unterschiede auf: 100% (211/211), Fertig.
tux@ubu:~/Downloads$
tux@ubu:~/Downloads$ du -sh doas/
508K        doas/
tux@ubu:~/Downloads$
tux@ubu:~/Downloads$
tux@ubu:~/Downloads$ grep -i pack doas/README.md
1 - The doas program has virtually no dependencies. So long as you have a compiler (such as the GNU Compiler or Clang) installed and GNU make (gmake on NetBSD, FreeBSD, and illumos). On illumos, the build-essential package will install all the necessary build tools.
tux@ubu:~/Downloads$
tux@ubu:~/Downloads$ ##   >> Voraussetzungen?
tux@ubu:~/Downloads$
tux@ubu:~/Downloads$ /bin/su -
Passwort:
my@bash $

Software bauen

Die einfach gehaltene Software bringt kein configure-Skript mit, daher geht es gleich mit ‚make‘ los. Die Option ‚-j2‘ lässt hier wieder zu, dass 2 CPU-Cores für das Bauen herangezogen werden können:

tux@ubu:~/Downloads$ make -j2

tux@ubu:~/Downloads$ cd doas/
tux@ubu:~/Downloads/doas$
tux@ubu:~/Downloads/doas$ make -j2

cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o doas.o doas.c
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o env.o env.c
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o compat/execvpe.o compat/execvpe.c
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o compat/reallocarray.o compat/reallocarray.c
/usr/include/unistd.h: In function ‘execvpe’:
compat/execvpe.c:110:10: warning: ignoring return value of ‘writev’, declared with attribute warn_unused_result [-Wunused-result]
  110 |    (void)writev(STDERR_FILENO, iov, 3);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compat/execvpe.c:61:5: warning: nonnull argument ‘name’ compared to NULL [-Wnonnull-compare]
   61 |  if ( (! name) || (*name == '\0') ){
      |     ^
yacc parse.y
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o compat/closefrom.o compat/closefrom.c
cc -include compat/compat.h -Icompat -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -c y.tab.c
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o compat/errc.o compat/errc.c
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o compat/getprogname.o compat/getprogname.c
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o compat/setprogname.o compat/setprogname.c
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o compat/strlcat.o compat/strlcat.c
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o compat/strlcpy.o compat/strlcpy.c
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o compat/strtonum.o compat/strtonum.c
cc -Wall -O2 -DUSE_PAM -DDOAS_CONF=\"/usr/local/etc/doas.conf\"  -D_GNU_SOURCE -include compat/compat.h -Icompat  -c -o compat/verrc.o compat/verrc.c
cat doas.1 | sed 's,@DOAS_CONF@,/usr/local/etc/doas.conf,g' > doas.1.final
cat doas.conf.5 | sed 's,@DOAS_CONF@,/usr/local/etc/doas.conf,g' > doas.conf.5.final
cat vidoas | sed 's,@DOAS_CONF@,/usr/local/etc/doas.conf,g' > vidoas.final
cat vidoas.8 | sed 's,@DOAS_CONF@,/usr/local/etc/doas.conf,g' > vidoas.8.final
cc -o doas doas.o env.o compat/execvpe.o compat/reallocarray.o y.tab.o  compat/closefrom.o compat/errc.o compat/getprogname.o compat/setprogname.o compat/strlcat.o compat/strlcpy.o compat/strtonum.o compat/verrc.o -lpam -lpam_misc
tux@ubu:~/Downloads/doas$ echo $?
0
tux@ubu:~/Downloads/doas$
tux@ubu:~/Downloads/doas$

Und schon ist das kleine Programm fertig, wir können es schon mal antesten:

tux@ubu:~/Downloads/doas$ ls -l
insgesamt 252
drwxrwxr-x 3 tux tux  4096 Nov 12 12:27 compat
-rwxrwxr-x 1 tux tux 42224 Nov 12 12:27 doas
-rw-rw-r-- 1 tux tux  2735 Nov 12 12:21 doas.1
-rw-rw-r-- 1 tux tux  2748 Nov 12 12:27 doas.1.final
-rw-rw-r-- 1 tux tux 13261 Nov 12 12:21 doas.c
-rw-rw-r-- 1 tux tux  6364 Nov 12 12:21 doas.conf.5
-rw-rw-r-- 1 tux tux  6377 Nov 12 12:27 doas.conf.5.final
-rw-rw-r-- 1 tux tux   576 Nov 12 12:21 doas.conf.sample
-rw-rw-r-- 1 tux tux  1724 Nov 12 12:21 doas.h
-rw-rw-r-- 1 tux tux 14088 Nov 12 12:27 doas.o
-rw-rw-r-- 1 tux tux  5800 Nov 12 12:21 env.c
-rw-rw-r-- 1 tux tux  8528 Nov 12 12:27 env.o
-rw-rw-r-- 1 tux tux  1294 Nov 12 12:21 LICENSE
-rw-rw-r-- 1 tux tux  2900 Nov 12 12:21 Makefile
-rw-rw-r-- 1 tux tux  6831 Nov 12 12:21 parse.y
-rw-rw-r-- 1 tux tux  4196 Nov 12 12:21 README.md
-rwxrwxr-x 1 tux tux  5355 Nov 12 12:21 vidoas
-rw-rw-r-- 1 tux tux  1888 Nov 12 12:21 vidoas.8
-rw-rw-r-- 1 tux tux  1901 Nov 12 12:27 vidoas.8.final
-rw-rw-r-- 1 tux tux  5381 Nov 12 12:27 vidoas.final
-rw-rw-r-- 1 tux tux 55745 Nov 12 12:27 y.tab.c
-rw-rw-r-- 1 tux tux 12816 Nov 12 12:27 y.tab.o
tux@ubu:~/Downloads/doas$
tux@ubu:~/Downloads/doas$
tux@ubu:~/Downloads/doas$
tux@ubu:~/Downloads/doas$ ./doas --help
./doas: invalid option -- '-'
usage: doas [-nSs] [-a style] [-C config] [-u user] command [args]
tux@ubu:~/Downloads/doas$
tux@ubu:~/Downloads/doas$ ##   >> Prima: Das Binary spukt die Kurzhilfe aus.

Als Root die Software installieren (an Ort und Stelle bringen, Rechte vergeben und evl. verlinken):

tux@ubu:~/Downloads/doas$ /bin/su
Passwort:

my@bash $ pwd
my@bash $ /home/tux/Downloads/doas
my@bash $
my@bash $ make install

mkdir -p /usr/local/bin
cp doas /usr/local/bin/
chmod 4755 /usr/local/bin/doas
cp vidoas.final /usr/local/bin/vidoas
chmod 755 /usr/local/bin/vidoas
mkdir -p /usr/local/man/man1
cp doas.1.final /usr/local/man/man1/doas.1
mkdir -p /usr/local/man/man5
cp doas.conf.5.final /usr/local/man/man5/doas.conf.5
mkdir -p /usr/local/man/man8
cp vidoas.8.final /usr/local/man/man8/vidoas.8

my@bash $
my@bash $
my@bash $ ls -l /usr/local/bin/doas
-rwsr-xr-x 1 root root 42224 Nov 12 12:30 /usr/local/bin/doas
my@bash $
my@bash $ ##   >> Richtig: Das SUID-Bit ist nötig, damit ein User mit seinem Passwort höhere Rechte erhält.

Gibt es aber auch ein Config-File? Wir suchen danach:

my@bash $ find /etc /usr/local/etc/ -cmin -7
my@bash $
my@bash $ ##    >> FEHLANZEIGE! Keine Datei abgelegt worden.

Im einfachsten Falle erzeugen wir uns selber eine Datei mit Hilfe von echo:

my@bash $ echo "permit tux as root cmd apt" > /usr/local/etc/doas.conf
my@bash $
my@bash $   >> Damit ist die Software installiert.

Testen der neuen Anwendung:

my@bash $ su - tux
tux@ubu:~$
tux@ubu:~$ doas --help
doas: invalid option -- '-'
usage: doas [-nSs] [-a style] [-C config] [-u user] command [args]
tux@ubu:~$
tux@ubu:~$ doas apt update
Password:
Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [107 kB]
Hit:2 http://de.archive.ubuntu.com/ubuntu focal InRelease
Get:3 http://de.archive.ubuntu.com/ubuntu focal-updates InRelease [111 kB]
Get:4 http://de.archive.ubuntu.com/ubuntu focal-backports InRelease [98.3 kB]
Get:5 http://security.ubuntu.com/ubuntu focal-security/main amd64 DEP-11 Metadata [24.2 kB]
Get:6 http://security.ubuntu.com/ubuntu focal-security/universe amd64 DEP-11 Metadata [56.6 kB]
Get:7 http://de.archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages [653 kB]
Get:8 http://de.archive.ubuntu.com/ubuntu focal-updates/main amd64 DEP-11 Metadata [232 kB]
Get:9 http://de.archive.ubuntu.com/ubuntu focal-updates/universe amd64 Packages [689 kB]
Get:10 http://de.archive.ubuntu.com/ubuntu focal-updates/universe i386 Packages [512 kB]
Get:11 http://de.archive.ubuntu.com/ubuntu focal-updates/universe amd64 DEP-11 Metadata [205 kB]
Get:12 http://de.archive.ubuntu.com/ubuntu focal-updates/multiverse amd64 DEP-11 Metadata [2468 B]
Get:13 http://de.archive.ubuntu.com/ubuntu focal-backports/universe amd64 DEP-11 Metadata [1768 B]
Fetched 2693 kB in 1s (2121 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.
tux@ubu:~$
tux@ubu:~$ doas apt upgrade
Password:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following packages were automatically installed and are no longer required:
  libfprint-2-tod1 libllvm9
Use 'apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
tux@ubu:~$
tux@ubu:~$ doas apt autoremove
Password:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
  libfprint-2-tod1 libllvm9
0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
After this operation, 69.4 MB disk space will be freed.
Do you want to continue? [Y/n]
  (Reading database ... 174644 files and directories currently installed.)
Removing libfprint-2-tod1:amd64 (1:1.90.2+tod1-0ubuntu1~20.04.2) ...
Removing libllvm9:amd64 (1:9.0.1-12) ...
Processing triggers for libc-bin (2.31-0ubuntu9.1) ...
tux@ubu:~$
tux@ubu:~$ ##  >> Funzt.  :-)
tux@ubu:~$

Have ‚a lot of fun…