Posts mit dem Label German werden angezeigt. Alle Posts anzeigen
Posts mit dem Label German werden angezeigt. Alle Posts anzeigen

Montag, 5. September 2016

Mercedes Me Concierge

Wenn der genauso gut funktioniert, muss ich wohl Fahrrad fahren.

Freitag, 8. Januar 2016

Diablo III Beta 2.4 PTR: Delseres Opus Magnum

Normalerweise bin ich kein Freund von Online-Services, die einem den Eindruck vermitteln, sie würden die tollste Erfindung seit geschnitten Brot sein, obwohl sie nur mit ein paar OpenSource-Tools zusammengeschustert sind. Aber in diesem Fall muss ich eine Ausnahme machen. Wenn man "mal schnell" ein Video zu einer animierten GIF-Grafik machen will, ist Ezgif.com ein prima Webseite. Man sollte natürlich tunlichst nur völlig öffentliche Videos dort hoch laden.

Das folgende GIF meiner Zauberin Horima aus der Diablo III PTR Beta 2.4 ist mit Hilfe des Dienstes entstanden. Aufgenommen habe ich mit OBS. Ezgif hat konvertiert, zugeschnitten und skaliert. Und mit Gimp habe ich das Fine-Tuning der Frames gemacht, damit die Animation sauber loopt.

Es ist meine erste Melee-Sorc seit Diablo I, die wirklich funktioniert. Alle Zauberinnen, die ich bislang geskillt habe, mussten sich schön weit von den Gegnern fernhalten. Auch die Experimente mit dem Sturmschild in Diablo II waren nicht wirklich effektiv. Aber mit dem 2.4er Patch hat Blizzard endlich mal ein Set mit ein paar praktischen legendären Ergänzungen geschaffen, mit denen man sich auch als Zauberin an die Gegner ran trauen kann. Es ist das Set "Delseres Opus Magnum". Das Set an sich ist nicht neu.

Und der dazu gehörige Helm ist es auch nicht.

Aber die neuen beziehungsweise überarbeiteten Zusatzgegenstände haben es in sich. Da wäre zuerst dieser Ring, der eine Schadensreduktion von 60% bietet. Und damit nicht genug: außerdem castet er quasi ständig Frost-Nova. Der Ring zusammen mit dem Helm lassen alles um einen herum so gut wie zum Stillstand kommen.

Als weitere Unterstützung gibt es die folgende Armschiene, die die Schilde verdoppelt.

Aber so richtig genial sind erst die nächsten Teilchen. Fragment der Bestimmung gibt eine 50% erhöhte Angriffsgeschwindigkeit für Spektralklinge und eine Erhöhung des Schadens von 200%. Damit alleine wäre Spektralklinge schon super schnell. Aber es kommt noch besser.

Der folgende Gürtel gibt nochmal eine Erhöhung der Angriffsgeschwindigkeit von Primärfertigkeiten um 50%. Damit ist Spektralklinge 100% schneller und geht ab wie eine Nähmaschine.

Das alleine ist angesichts der 2000% Schadenserhöhung durch das Set schon recht knackig. Aber so richtig knallt es erst mit dem neuen Triumvirat. Der erhöht nämlich den Schaden von Arkankugel um satte 200%. Und das ist auch noch drei mal stapelbar. Zusammen mit der 100%igen Geschwindigkeitserhöhung von Spektralklinge hat man die drei Stapel quasi sofort.

Und wem das immer noch nicht reicht: es gibt noch ein Sahne-Häubchen: Instabiles Zepter. Das lässt Arkankugel doppelt explodieren und steigert zusätzlich noch den Schaden von Arkankugel um 65%. Zusammen mit den 600% vom Triumvirat und den 2000% vom Set knallt man damit alles um, was nicht bei drei auf den Bäumen ist.

Damit habe ich gerade relativ entspannt im Solo ein Level 60 Portal beendet. Zugegeben am Ende hat mich der Steinsänger mit seinem Sprungangriff ein paar mal umgehauen aber bis dahin war alles problemlos.

Ich bin mal gespannt, wie schnell die Items nach der Beta droppen. Die Zeiten des Überflusses dürften in Kürze vorbei sein.

T_T

Sonntag, 6. September 2015

Windows-Schriften unter Linux verwenden

Wer unter Windows eine virtuelle Maschine verwendet, um Linux zu benutzen, kann sehr einfach die Windows-Schriften auch unter Linux verwenden. Dazu muss lediglich das Verzeichnis, in dem sich unter Windows die Schriften befinden als Shared-Folder für den Linux-Gast freigegeben werden. Die entsprechende Option sieht VirtualBox folgendermaßen aus.

Mit Hilfe des Namens kann das Verzeichnis unter Linux eingebunden werden. Dazu muss erst ein Mount-Point angelegt werden.

mkdir /usr/local/share/fonts/windows

Anschließend kann ein Eintrag in der fstab-Datei hinzugefügt werden, damit das Verzeichnis beim Start automatisch eingebunden wird.

echo fonts /usr/local/share/fonts/windows vboxsf ro,comment=systemd.automount 0 0 >> /etc/fstab

Wer sein System nicht neu starten will, muss jetzt das Verzeichnis manuell einbinden.

mount fonts

Abschließend muss der Font-Cache aktualisiert werden. Das kann je nach Anzahl der Fonts unter Windows etwas dauern.

fc-cache -fv

Jetzt stehen die Schriften im System zur Verfügung und können in den entsprechenden Programm ausgewählt werden. Zum Beispiel Tahoma für XFCE ...

... oder Emacs mit Lucida Console wie damals auf den SPARCstations unter OpenWindows.

Nachtrag

Emacs dazu zu überreden, dass das richtige Font-Hinting verwendet wird, gestaltet sich schwieriger als erwartet. Der Font-Dialog erlaubt es nicht, das Font-Hinting auszuwählen. Wer es trotzdem verwenden will darf nicht über die Emacs-Customization die Schrift auswählen. Statt dessen muss sie als X11-Resource in der Datei ~/.Xresources definiert werden. Für Lucida-Console auf einem 72dpi-Display sieht der Eintrag folgendermaßen aus:

Emacs.font: Lucida Console-14:antialias=true:hinting=true:autohint=false:hintstyle=3

Bei Systemen mit einer höheren Auflösung kann man auch kleinere Schrift-Größen wählen.

Mittwoch, 12. August 2015

Absätze durch Zeilenumbrüche in MS-Word ersetzen

Wenn man Quellcode in Word einfügt, kommt es oft dazu, dass an jedem Zeilenende ein Absatz eingefügt wird. Wenn Absätze so formatiert sind, dass zwischen ihnen ein Leerraum sein muss, führt das dazu, dass man zwischen allen Code-Zeilen einen Abstand hat. Die Lösung für das Problem ist, den Absatz zu löschen und durch einen Zeilenumbruch (Shift-Return) zu ersetzen. Bei längeren Listings ist das ein sehr nerviger Vorgang.

Man kann sich das Problem vereinfachen, indem man die Suchen-und-Ersetzten-Funktion von Word nutzt. Ein Absatz ist in Word die Zeichen-Sequenz "^p" und ein Zeilenumbruch "^l". Damit kann man in dem betreffenden Code-Block alle Absätze durch Zeilenumbrüche ein einem Rutsch ersetzen.

Donnerstag, 8. Januar 2015

Langsamer ist besser!

Die Programmiersprache C gilt als super schnell und optimal geeignet für Hardware-nahe Aufgaben. Im Internet gibt es reichlich Verweise darauf, wie viel schneller C ist und wie viel langsamer im Gegensatz dazu interpretierte Sprachen sind. Das Problem an solchen Vergleichen ist, dass sie Äpfel mit Birnen vergleichen. Das wird deutlich, wenn man sich das folgende Beispiel ansieht.

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
  int8_t a, b, c;

  a = atoi (argv[1]);
  b = atoi (argv[2]);

  c = a + b;

  printf ("%d\n", c);

  return 0;
}

Das Programm erwartet zwei Zahlen als Argument, addiert sie und gibt das Ergebnis aus. Es lässt sich ohne Fehler und Warnungen übersetzen.

cc -Wall -c -o c-speed.o c-speed.c
cc c-speed.o -o c-speed
Und auf den ersten Blick scheint es ganz gut zu funktionieren.

$ ./c-speed 1 2
3
Auf den zweiten Blick auch noch.

$ ./c-speed 10 20
30

Nur auf den dritten leider nicht mehr.

$ ./c-speed 100 200
44

Das Problem ist, dass für die Speicherung der Zahl 8 Bit verwendet wurden. Integer-Zahlen werden von heutzutage üblichen Architekturen als Zweierkomplement gespeichert. Das bedeutet, dass ein Bit für das Vorzeichen reserviert wird und die restlichen für die Zahl. Der Wertebereich ist somit -128 bis 127. Darin lässt sich eine 100 speichern aber keine 200 und erst recht keine 300.

Die binäre Darstellung der drei Zahlen sieht folgendermaßen aus.

100 ⇒ 0 1 1 0 0 1 0 0
200 ⇒ 0 1 1 0 0 1 0 0 0
300 ⇒ 0 1 0 0 1 0 1 1 0 0

Auf der rechten Seite ist das niedrigstwertige Bit und auf der linken das höchstwertige Bit. Die führende Null gibt an, dass es sich um eine positive Zahl handelt. Für die 200 reichen somit 8 Bit nicht mehr aus, es werden 9 benötigt. Und für die 300 werden schon 10 benötigt.

C ist dieser Sachverhalt völlig egal. Statt den Überlauf zu erkennen wird einfach mit dem weiter gerechnet, was übrig bleibt nachdem die übergelaufenen Bits weggeschmissen wurden. Dafür gibt es auch eine hochtrabende Bezeichnung: rechnen in Restklassenringen. Und das ist etwas völlig anderes als das, was Schülern in Unter- und Mittelstufe als "Rechnen" beigebracht wird.

In diesem konkreten Fall bedeutet es, dass das neunte Bit der 200 und das neunte und zehnte Bit der 300 über Bord gehen. Allerdings kommt es bei der 300 dazu gar nicht erst, weil durch den Wegfall des neunten Bits die 200 negativ wird, weil jetzt das höchste Bit nicht mehr eine Null sondern eine Eins ist.

200 ⇒ 0 1 1 0 0 1 0 0 0
1 1 0 0 1 0 0 0 ⇒ -56

Somit entsteht bei der Addition gar kein Überlauf, da C aus der Addition eine Subtraktion macht: 100 + (-56) = 44. Somit wäre erklärt wie C bei der Addition von 100 und 200 auf 44 kommt. Und da C keine Addition sondern eine Restklassen-Addition durchgeführt hat, hat es auch alles richtig gemacht. Dass weder das Restklassen-Ergebnis noch die Erklärung, was genau es denn ist, einem normal sterblichen Anwender irgend etwas bringen, der auf seinem Kontoauszug eine 44 liest, obwohl er gerade 200€ eingezahlt hat und zuvor noch 100€ auf dem Konto waren, dürfte offensichtlich sein.

Ein typischer C-Programmierer wird nun darauf hinweisen, dass man ja auch mehr Bits für die Speicherung von Zahlen verwenden kann. Die Zeiten, dass man mit Prozessoren auskommen musste, die nur 8 Bit verarbeiten konnten sind lange vorbei und somit könnte man zur Speicherung der Zahl int16_t oder int32_t oder int64_t verwenden. Schon int16_t würde für die Speicherung von 100, 200 und 300 völlig ausreichen, da für die 300 nur 10 Bit nötig waren.

Auf den ersten Blick erscheint das einleuchtend aber das ist nicht wirklich eine Lösung für das Problem. Das Problem ist lediglich aufgeschoben und aufgeschoben ist bekannter Weise nicht aufgehoben. Die Aufschiebung besteht darin, dass der Überlauf bei der Verwendung von int16_t nicht mehr bei Zahlen größer als 127 auftritt sondern bei Zahlen größer als 32767. Das Spielchen kann man jetzt weiter treiben und immer größere Wortbreiten verwenden.

8 Bit:127
16 Bit:32767
32 Bit:2147483647
64 Bit:9223372036854775807
128 Bit:170141183460469231731687303715884105727
256 Bit:57896044618658097711785492504343953926634992332820282019728792003956564819967

Die 256 Bit erscheinen auf den ersten Blick recht groß und man könnte auf die Idee kommen, die Wahrscheinlichkeit, dass es in einem Programm, das mit 256 Bit Zahlen arbeitet, zu einem Überlauf kommt, könne man jetzt wirklich vernachlässigen.

Allerdings sollte man sich klar machen, dass es durchaus Anwendungen gibt, bei denen längere Zahlen benötigt werden. Eine RSA-Verschlüsselung mit 256 Bit Zahlen ist heutzutage als lächerlich zu betrachten, da zur Zeit mindestens 2048 Bits benötigt werden, um einigermaßen sicher zu sein. Und ebenso wichtig dürfte der Sachverhalt sein, dass man nicht davon ausgehen darf, dass ein Programm in dem vom Programmierer vorgesehenen Zahlenbereich arbeitet. Jemand, der eine Sicherheitslücke in einer Software aufspüren will, wird selbstverständlich ein Programm gerade mit solchen Eingaben füttern, die außerhalb dessen liegen, was der Programmierer der Software ursprünglich bei der Planung und Entwicklung als normal angesehen hatte.

Das bedeutet, dass das typische Verhalten eines C-Programmierers, Zahlenüberläufe zu ignorieren, ein sehr großes Sicherheitsrisiko darstellt. Die Geschwindigkeit, die man dadurch erreicht, dass man einfach ungenau arbeitet, wird durch Fehler und Sicherheitsprobleme erkauft. Und somit ist die Aussage "C sei schnell" mehr ein Fluch als ein Segen.

Wenn man also Zahlenüberläufe wirklich vermeiden will, dann ist die logische Konsequenz, dass man eine Zahl nicht mehr in etwas speichern kann, das durch den Restklassenring der gerade zur Verfügung stehenden CPU beschränkt ist. Denn genau das macht C. Statt dessen muss man eine Zahl als eine sog. Bignum oder Big-Integer speichern. Das wiederum geht auch in C unter Verwendung der GMP-Bibliothek. Aber dadurch verliert man die sagenumwobene Geschwindigkeit von C, weil eine Zahl nicht mehr mit nur einem CPU-Befehl addiert werden kann. Statt dessen sieht die Rechnung mit Bignums folgendermaßen aus.

  1. Dekodierung der Zahl von der in der Bignum-Bibliothek gewählten Kodierung in eine für die verwendete CPU verständliche Darstellung.
  2. Durchführung der gewünschten Rechnung unter zu Hilfenahme von diversen von der CPU bereitgestellten Operationen.
  3. Codierung der Zahl in die von der Bignum-Bibliothek benötigte Form.
Und dieser Aufwand muss für jede Addition, jede Multiplikation und jede sonstige Rechenoperation gemacht werden. Und damit ist auch sofort klar, dass das alles andere als schnell ist sonder richtig langsam. Und das ist auch gut so. Denn in diesem Fall bedeutet Langsamkeit Richtigkeit.

Wer also der Meinung ist, in C zu programmieren sei eine gute Idee, weil die Programme so schön schnell sind oder die Verwendung des Java-Typs int sei eine gute Idee, weil er so viel schneller als BigInteger ist, dem kann ich nur mein Beileid aussprechen. Die Schnelligkeit von C ist keine Eigenschaft der Sprache, sondern man bezahlt für sie in barer Münze. Heutzutage kann man Exploits wie geschnitten Brot kaufen. Wer also sicher programmieren will, sollte darauf Wert legen, dass seine Programmiersprache keine Werbung damit macht, wie schnell sie sei. Statt dessen gilt beim Programmieren wie in der 30-Zone vor dem Kindergarten:

Langsamer ist besser!

Mittwoch, 7. Januar 2015

Raspberry Pi ohne Bildschirm und Tastatur booten

Mit Hilfe eines seriellen Kabels kann man den Raspberry Pi ganz ohne Bildschirm und Tastatur booten. Und wenn man keine großen Stromverbraucher an den USB-Ports des Raspis hängen hat, reicht auch die normale USB-Stromversorgung über den GPIO-Port. Ein Test-Aufbau auf dem heimischen Schreibtisch vereinfacht sich dadurch erheblich.

Man benötigt für das Login über die serielle Schnittstelle ein speziell für den Raspberry Pi angebotenes serielles USB-Kabel. Ich habe meins für 8,80€ bei Reichelt bestellt. Es nennt sich dort "USB zu TTL für Raspberry Pi, 1,0 m" und die Artikelbezeichnung ist "RPI USB TTL". Man kann kein "gewöhnliches" RS232-USB-Kabel benutzen und die entsprechenden Adern verbinden, weil die Pegel der RS232-Schnittstelle für den GPIO-Port des Raspberry Pi den Tod bedeuten.

Wenn man den Raspi über das Kabel mit dem Computer verbindet, steckt man die rote Ader für die Stromversorgung praktischer weise erst mal nicht. Andernfalls würde er direkt booten und man könnte den Boot-Vorgang im Terminal nicht sehen, da Windows erst mal den Treiber für die serielle Schnittstelle installieren muss.

Wenn Windows den Treiber richtig installiert hat, taucht im Gerätemanager der entsprechende COM-Port mit der Nummer auf, die man für Putty benötigt.

In meinem Fall ist es COM15. Die serielle Schnittstelle des Raspi wird meist mit 115200 Baud betrieben und nicht wie früher üblich mit 9600 Baud. Wenn man in Putty den "Serial" "Connection type" auswählt, kann man COM-Port und Baud-Rate setzen.

Jetzt kann man dem Raspi mit dem roten Kabel seine Versorgungsspannung geben. Die vier Adern des seriellen Kabels müssen folgendermaßen angeschlossen werden

Rot: auf den äußeren beiden Beinen sind die 5 Volt Versorgungsspannung
Schwarz: das dritte Bein ist Ground
Weiß: das vierte Bein ist TX (GPIO 14)
Grün: und das fünfte Bein ist RX (GPIO 15)

Wenn man die Adern richtig gesteckt hat, fängt der Raspi direkt an zu booten.

In Putty kann man parallel verfolgen, wie die Boot-Meldungen durch rauschen. Dank der hohen Baud-Rate geht das angenehm schnell.

Und schließlich kann man sich über die serielle Schnittstelle auch anmelden, ohne dafür eine Tastatur oder einen Monitor bemühen zu müssen.

Hintergrund

Warum funktioniert das so wie oben beschrieben? Grundsätzlich funktioniert eine serielle Konsole an jedem System, das eine serielle Schnittstelle hat. Allerdings muss man jeder Komponente, die eine Ausgabe erzeugt oder Eingaben erwartet, separat mitteilen, dass sie die serielle Schnittstelle nutzen soll. Bei klassischen PC-Systemen sind das die folgenden gemäß der Reihenfolge, wie sie beim Boot aktiv sind:
  1. BIOS: zum Beispiel Phoenix, AMI, OpenBIOS etc.
  2. Boot-Loader: zum Beispiel Grub, Syslinux etc.
  3. Kernel: zum Beispiel Linux.
  4. Konsole: zum Beispiel agetty aus der "util-linux"-Programm-Sammlung.
Viele kommerzielle BIOSe sind nicht in der Lage, für die Ein- und Ausgabe eine serielle Schnittstelle zu verwenden. Man findet die Funktion meist nur bei Server-BIOSen oder bei BIOSen für zum Beispiel Network-Appliances wie dem ALIX-Board. Deswegen ist es heutzutage bei der Verwendung von PC-Hardware meist unüblich geworden, die Konsole auf die serielle Schnittstelle zu legen, was ich aber eher als Mangel betrachte.

Beim Raspi mit Raspbian ist die Situation erfreulicher Weise anders und auch etwas einfacher, weil er weder ein interaktives BIOS noch einen interaktiven Boot-Loader hat. Somit muss man nur noch dem Kernel und der Konsole sagen, dass sie die serielle Schnittstelle verwenden sollen.

Der Kernel wird beim Raspi-Boot-Loader über die Datei "cmdline.txt" auf der SD-Karte parametrisiert. Nachdem das System gebootet ist, ist die SD-Karte unter dem Verzeichnis /boot gemountet:

pi@raspberrypi:~$ cat /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
Der relevante Paramter ist console=ttyAMA0,115200. Die Syntax für den Parameter ist in der Linux-Kernel-Dokumentation zu finden. Das erste Argument ist das serielle Gerät und das zweite die Baud-Rate.

Die Linux-Konsole wird durch den ersten aller Prozesse also Init gestartet. Init wiederum wird durch die Datei /etc/inittab konfiguriert. In der Inittab stehen Programm-Aufrufe pro Runlevel. Der normale Runlevel ist bei Raspbian 2:

pi@raspberrypi:~$ runlevel
N 2
Dem entsprechend muss in der Inittab für Runlevel 2 ein Aufruf von getty konfiguriert sein:
pi@raspberrypi:~$ awk -F: '/^[^#]/ && $2~2' /etc/inittab
id:2:initdefault:
l2:2:wait:/etc/init.d/rc 2
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
1:2345:respawn:/sbin/getty --noclear 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
Und dort ist der Aufruf auch in der letzten Zeile zu finden. Wichtig ist, dass überall die gleiche Baud-Rate verwendet wird, da man zum Zeitpunkt der Übergabe der serielle Schnittstelle vom Kernel an Getty in Putty schlecht die Baud-Rate ändern kann.

Wenn man den GPIO-Port 14 für was anderes wie zum Beispiel eine Strom-Trennung verwenden möchte, könnte man den Raspi auch über zwei klassische USB-Seriell-Adapter mit dem PC verbinden: einer käme in den PC und der andere in einen USB-Port des Raspis und verbunden würden die beiden über ein Null-Modem-Kabel. Damit das funktioniert muss im Kernel der passende Treiber für den USB-Seriell-Adapter sein und man müsste anstatt ttyAMA0 das entsprechende Gerät für den USB-Seriell-Adapter verwenden. Typischerweise wäre das ttyUSB0. Allerdings würde dies eine Anpassung am Standard-Raspbian-Image erfordern, was bedeutet, dass man unter Windows die zweite Partition der SD-Karte mounten muss, um dort die Inittab zu ändern. Unter Windows gehört der Schreib-Zugriff auf EXT4-Partitionen nicht zu den Standard-Funktionen. Von Paragon wird ein Tool angeboten, mit dem das möglich sein soll. Wie gut das funktioniert bleibt zu testen.

Dienstag, 30. Dezember 2014

Linphone auf dem Iphone für T-Online konfigurieren

Wer zwangsweise auf VoIP umgestellt wurde, hat die Möglichkeit auf dem Handy einen SIP-Client zu benutzen, um über die ehemals "Festnetz"-Nummer zu telefonieren. Wer dabei nicht von Google und Co belauscht werden will, benötigt einen Open-Source-SIP-Client, um sicher zu stellen, dass die Software keine Backdoors enthält. Linphone ist freie Software und auch für das Iphone verfügbar.

Leider funktioniert der Konfigurationsassistent nicht. Aber wenn man unter "Settings" die Option "Advanced account" aktiviert kann man die richtigen Daten eingeben.

User nameTelefonnummer mit Ortsvorwahl und 0 aber ohne Landesvorwahl
User IDT-Online-Nummer mit @t-online.de am Ende
Passworddas Passwort, das auch für das Kundencenter benötigt wird
Domaintel.t-online.de
Proxy
TransportTCP

Leider geht TLS als Transport nicht, was sehr schwach ist, da so wahrscheinlich das T-Online-Passwort im Klartext über das Netz geht. So können unsere "befreundeten" Geheimdienste besser mitlesen. Naja drauf geschissen, für etwas Blabla wird es reichen.

Montag, 17. November 2014

Undelete für "rm *"

Verdammte Scheiße! Gerade ist es mir wieder passiert. Das letzte mal ist schon ein paar Jahre her. Und ich hätte nicht gedacht, dass es mir nochmal passiert. Aber im Eifer des Gefechts, wenn man nicht genau hinsieht und die Tab-Completion auf einer langsamen SSH-Leitung einem Dinge vorgaukelt, die nicht wirklich so sind wie sie scheinen, ja so ist es mir passiert. Und natürlich habe ich mir gespart die Arbeit der letzten paar Tage einzuchecken, will man ja immer erst machen, wenn es wirklich rund läuft. Scheiß drauf! In Zukunft wird jeder Müll eingecheckt. Aber das hilft jetzt leider nicht weiter.

Gelöschte Daten auf einem Linux-Dateisystem zu rekonstruieren ist nicht so einfach und wenn einem ein solches Malheur passiert ist, gilt es Ruhe zu bewahren. Jeder weitere Schreibzugriff auf die betreffende Platte kann dazu führen, dass die gelöschten Daten unwiederbringlich verloren sind. Natürlich kann man die Platte wegmounten und mit mit diversen Tools ein Backup machen, um darin noch was zu finden. Wenn man aber über SSH auf einem Produktionssystem ist, stellen solche Tools meist keine Option dar.

Was aber geht ist ein grep auf das Raw-Device. Und in meinem Fall hat genau das geholfen. Dazu muss man sich aber an den Anfang der Datei erinnern. Wenn man den noch kennt, kann man grep dazu überreden eine Binärdatei wie eine Textdatei zu behandeln. Mit den Optionen -B und -A kann man den Bereich vor und hinter der Überschrift eingrenzen und less zeigt die Daten an, ohne das Terminal zu schrotten.

grep --binary-files=text -B 1 -A 500 \
  '## Various Bash functions' \
  /dev/disk/by-uuid/6989be6b-e743-419a-bd8b-bc877756dfe2 |
less

Puh nochmal Glück gehabt:

Donnerstag, 13. November 2014

Apple 20 Jahre später und kein bischen besser

Ich bin jetzt leider dazu verdammt, ein Apple-Produkt zu benutzen. Seit 20 Jahren ist der Kelch zum Glück an mir vorüber gegangen aber jetzt gibt es in meiner Firma keine anderen Telefone mehr als solche von Apple. Der ersten Schock, an dessen Überwindung ich zur Zeit arbeite, hat mich direkt in die frühen 90er zurück katapultiert: das dumme iPhone hat keine Zurück-Taste. Schon damals hat Apple an den Tasten gespart und der Maus nur eine davon spendiert, während jede Workstation seit ewigen Zeiten drei Tasten hatte. Aber damals, anders als jetzt, war ich nicht dazu gezwungen, mit dem wenigen auskommen zu müssen, was Apple seinem typischerweise technisch beschränkten Klientel zuzumuten sich wagt.

Nachdem ich feststellen musste, dass auch die Musik noch die gleiche ist wie in den 90ern, konnte ich jedoch mit großem Erstaunen eine echte Veränderung beobachten: Mosaic heißt jetzt Safari. Von dem, was der neue iPhone-Browser kann, unterscheidet er sich allerdings wiederum kaum von dem aus den 90ern: Plugins gehen heute genauso wenig wie damals. Und damit wird es jetzt wirklich lästig. Denn anders als damals in den Anfängen des Internets, wo man private Vereine gründen musste, um überhaupt ohne einen Uni-Computer ins Internet kommen zu können, ist heute ein Leben ohne Browser-Plugins, zumindest für mich, nicht mehr vorstellbar. In den 90er gab es fast nur sinnvolle Inhalte im Internet, heute dagegen gibt es fast nur noch sinnlose Inhalte. Und deswegen sind die beiden wichtigsten aller Browser-Plugins Adblock und PwdHash: Adblock, um sich ungefragte Inhalte vom Leibe zu halten, und PwdHash, um sich unliebsame Zeitgenossen vom Leibe zu halten. Für beides gilt: Fehlanzeige auf einem iPhone!

Wenn man der Sache versucht auf den Grund zu gehen, stellt man fest, dass Apple anscheinend Browser-Plugins mit Gewalt verhindern will. Chrome für iPhone verfügt über keine Möglichkeit, Browser-Plugins zu verwenden und Firefox gibt es erst gar nicht. Und bei der erfolglosen Durchsicht der übrigen Browser-Varianten ist mir auch klar geworden, wo bei einem iPhone die Prioritäten liegen. Apple ist voll und ganz damit beschäftigt, die Bedürfnisse amerikanischer Prüderie zu befriedigen, und hat somit keine Zeit mehr, was Sinnvolles zu tun.

Man achte auf die folgende Klassifikation eines Internet-Browsers für das iPhone.

Dieser Browser verfügt über stark ausgeprägte Szenen mit erotischen Anspielungen, weswegen er erst mit 17 Jahren benutzt werden kann.

Eine viertel Stunde später: ich habe wieder eine trockene Hose an. Die alte musste ich leider wechseln, da ich mich vor lachen bepisst hatte.

Einem Browser zu attestieren, er sei Jugend gefährdend, ist ungefähr so hellsichtig wie einem Optiker zu unterstellen, er würde Prostitution fördern, weil man mit der Brille die Nutten erkennen kann. Aber gut, dass Apple uns das jetzt mal richtig klar gemacht hat. Und Brillen kaufen ist ja auch mitunter eine kostspielige Angelegenheit. Das Geld kann man ja viel besser in Apple-Produkte investieren. Das erinnert mich irgendwie an das Drama, eine Apple-ID ohne Kreditkarte zu bekommen. Aber das ist eine andere Geschichte...

Nun was ist das Fazit dieser Geschichte: ein Telefon bleibt ein Telefon und ist zu nichts mehr zu gebrauchen als zum telefonieren. Auch daran hat sich seit den 90er nichts geändert.

Sonntag, 9. November 2014

Die Dreistigkeit der Placebo-Mafia

Unter der Domäne www.cialis20mgkaufen.net findet sich folgende schmucke Webseite.

Die Webseite betitelt sich selbst als "Geprüfter Deutscher Shop". Wenn man sich das Impressum der Seite ansieht, sieht man sofort, dass der Laden in der urdeutschen Gemeinde Venlo angesiedelt ist. Vielleicht war Deutschland in den Grenzen von Kaiser Karl dem Großen gemeint. Einem technisch versierten Beobachter fällt außerdem noch auf, dass das Impressum als Grafik hinterlegt ist. Dafür kann es eigentlich nur einen Grund geben: man will erreichen, dass die Information möglichst schlecht automatisch gelesen werden kann.

Wenn man sich dann den Inhalt der Whois-Datenbank für die DNS-Registrierung ansieht, stellt man fest, dass die Firma "Web Domains By Proxy" aus Pakistan die Domäne registriert hat. Man hat keine Mühen gescheut, seine Identität zu verschleiern.

Aber der größte Witz ist das Testergebnis von Stiftung Warentest. Angeblich wurden in Heft 06/2011 "Potenzmittel Online Apotheken aus Europa" getestet. Wer sich den Titel ausgedacht hat, sollte vielleicht beim Postillon anheuern. Wenn man sich also das tatsächliche Inhaltsverzeichnis von Heft 06/2011 ansieht, findet man den besagten Test natürlich nicht.

Vermutlich gilt das gleich für sämtliche anderen Logos auf der Seite: alles frei erfunden.

Sehr hübsch ist auch das Google+-Profil von unserem Apotheker.

Der gute Mann wohnt in Berlin und hat seine Versandlager laut Impressum in München, Venlo und UK. Die immense Reisetätigkeit, die eine solche Kombination nach sich zieht, ist vermutlich auch der Grund, warum er leider bislang noch keine Gelegenheit hatte, die deutsche Sprache zu lernen.

Wenn man dann das süße Profilfoto nimmt und bei Google eine Suche nach ähnlichen Bildern macht, findet man einen Dr. med. Ulrich Albers.

Man kann also mit ziemlicher Sicherheit sagen, dass auf der zitierten Webseite so ziemlich alles gelogen ist. Wer dort kauft, kann sein Geld auch direkt in den Gulli werfen. Ein Beispiel für die ganz alltägliche Internet-Abzocke.

Update

Eigenartiger Weise scheint Google ein Interesse daran zu haben, dass die Machenschaften von dubiosen Internet-Anbietern nicht veröffentlicht werden. Denn wie von Geisterhand sind die Screenshots, die ich von der dubiosen Webseite gemacht hatte, aus meinem Picasa-Konto gelöscht worden, ohne dass mich irgend jemand über diese Vorgänge informiert hat. Ich bin mal gespannt, ob die fleißige Bienchen, die sich für die Interessen von Internetbetrügern einsetzen, auch meinen Blog besuchen.

Mittwoch, 28. Mai 2014

Floppy-Boot-Sektor debuggen unter Windows

Der folgende Text beschreibt wie man auch unter Windows einen Floppy-Boot-Sektor debuggen kann. Dazu braucht man die folgenden Programme.

Editor
Ein einfacher Editor, der auch ein bisschen Syntax einfärben kann, ist Notepad++.
Terminal
Ein brauchbares Terminal, das auch in der Lage ist, Tabs anzuzeigen ist ConEmu. Man benötigt meistens vier Fenster: Emulator, Monitor, Debugger und Compiler.
Assembler
Um einen Boot-Sektor debuggen zu können, muss man ihn erst einmal erzeugen. Das geht mit NASM ganz gut.
Emulator
Am einfachsten kann man einen Boot-Sektor in einem Emulator debuggen. Der wohl mächtigste Emulator ist Qemu. Fertige Binaries für Windows gibt es bei Stefan Weil.
Debugger
Qemu arbeitet am besten mit dem GNU Debugger GDB zusammen. Fertige Binaries für Windows gibt es bei Equation Solution.

Wie man die Programme installiert und die PATH-Variable setzte dürfte vermutlich jedem klar sein, der Boot-Sektoren debuggen will, weshalb ich darauf nicht weiter eingehe.

Boot-Sektor

Somit stellt sich als nächstes die Frage, wie ein Boot-Sektor erstellt werden kann. Das Geheimnis des Boot-Sektors ist relativ schnell erzählt. Es sind 512 Bytes Code, an deren Ende sich die Bytes 55h und AAh befinden. Da Intel den Speicher im Little-Endian-Format organisiert handelt es sich um das 16 Bit-Wort AA55h. Der Boot-Sektor wird vom BIOS an die Adresse 7C00 geladen und ausgeführt. Beim Start steht CS auf 0 und IP auf 7C00. Free Source Codes shows two example boot sectors: one doing nothing and one printing some dots on the the screen. This is the listing of the one printing dots.

     1                                   _Text SEGMENT PUBLIC USE16
     2          ******************       warning: ignoring unknown section attribute: "USE16"
     3                                  ;************************************************************
     4                                  ; Program entry point
     5                                  ; Currently we are at 0:7C00
     6                                  ;************************************************************
     7                                  org 0
     8                                  EntryPoint:
     9                                      ; Would have preferred 07C0:0000
    10                                      ; Dealing with an offset that starts at 0 is easier
    11                                      ; So do a far jump to 07C0:????
    12                                  
    13 00000000 EA[2700]C007                jmp 0x07C0:AfterData
    14                                  
    15                                  ; Your Data goes here!
    16 00000005 57656C636F6D652074-         BOOT_MSG db 'Welcome to BOOT SECTOR CODE!',10,13,0
    17 0000000E 6F20424F4F54205345-
    18 00000017 43544F5220434F4445-
    19 00000020 210A0D00           
    20 00000024 2E2000                      ACTIVITY db '. ',0
    21                                  
    22                                  AfterData:
    23                                  ; update DS to be 7C0 instead of 0
    24 00000027 0E                      push CS
    25 00000028 1F                      pop DS
    26                                  
    27                                  ; update ES also
    28 00000029 0E                      push CS
    29 0000002A 07                      pop ES
    30                                  
    31                                  ; create stack
    32 0000002B B80000                  mov ax, 0x0000
    33 0000002E 8ED0                    mov ss, ax
    34 00000030 BCFFFF                  mov sp, 0xFFFF
    35                                  
    36                                  ; display boot message...
    37 00000033 8D36[0500]              lea si, [BOOT_MSG]
    38 00000037 E81500                  call Print
    39                                  
    40                                  ; Go into a hang printing dots
    41                                  DIE_LOOP:
    42 0000003A 8D36[2400]              lea si, [ACTIVITY]
    43 0000003E E80E00                  call Print
    44 00000041 B9FFFF                  mov cx, 0xffff
    45                                  delay1:
    46 00000044 BBFF0F                  mov bx, 0xfff
    47                                  delay2:
    48 00000047 4B                      dec bx
    49 00000048 75FD                    jnz delay2
    50 0000004A 49                      dec cx
    51 0000004B 75F7                    jnz delay1
    52 0000004D EBEB                    jmp DIE_LOOP
    53                                  
    54                                  ;************************************************************
    55                                  ; Procedure print
    56                                  ; prints a zero terminated string pointed to by si
    57                                  ;************************************************************
    58                                  Print:
    59 0000004F 50                      push ax
    60 00000050 B40E                    mov ah, 14 ; BIOS code for screen display
    61 00000052 FC                      cld
    62                                  print_loop:
    63 00000053 AC                      lodsb ; moving the character to be displayed to al
    64 00000054 08C0                    or al, al ; checking if the char is NULL
    65 00000056 7404                    jz printdone
    66 00000058 CD10                    int 10h ; Calling BIOS routine
    67 0000005A EBF7                    JMP print_loop
    68                                  
    69                                  printdone:
    70 0000005C 58                      pop ax
    71 0000005D C3                      ret
    72                                  ; End of print procedure...
    73                                  
    74                                  
    75                                  ; Make the file 512 bytes long
    76 0000005E 00<rept>                TIMES 510-($-$$) DB 0 
    77                                  
    78                                  ; Add the boot signature
    79 000001FE 55AA                    dw 0AA55h

Das obige Listing entsteht beim übersetzten des Quelltextes:

nasm boot.asm -l boot.lst -o boot.bin

Debug-Emulation

Der Boot-Sektor kann direkt von Qemu als Floppy-Image zum booten verwendet werden. Wenn man das aktuelle Terminal durch den Aufruf von Qemu nicht blockieren will, kann man sich ein Batch-Script machen und Qemu mit "start /b" starten.

start /b qemu-system-i386 -gdb tcp:127.0.0.1:1234 -monitor telnet:127.0.0.1:1235,server,nowait -S -localtime -fda boot.bin -boot a -no-fd-bootchk

Die Option -gdb öffnet Port 1234 und ermöglicht den Remote-Zugriff durch den Debugger. Das geht im GDB mit folgendem Befehl.

target remote localhost:1234

Und die Option -monitor ermöglicht es mit Telnet auf den Qemu-Monitor zugreifen zu können.

telnet localhost 1235

Da die virtuelle Maschine über die Option -S im gestoppten Modus gestartet wurde, muss man im GDB das System mit c erst starten. Wenn alles richtig funktioniert, werden im Qemu-Fenster der Reihe nach einzelne Punkte ausgegeben.

Dienstag, 6. Mai 2014

Wolfs-Rechtschreibprüfung

Gerne hätte ich gewusst, wie Microsoft auf die Idee kam, dass ich "wollte" durch "Wolfs" ersetzten müsste.

Wie gut dass es noch keinen Sprachassistenten von Microsoft gibt.

Sonntag, 9. März 2014

Drehzahl und Vorschub zum Fräsen von Aluminium

Ausgangspunkt meiner Üerlegung war die Frage, ob man mit einer hochwertigen Bohrmaschine auch Aluminum fräsen kann.

Auf den Seiten der Gienger Industrie Service (GIS) findet man eine nützliche Empfehlung zur Berechnung der Geschwindigkeit, mit der man Aluminium fräsen sollte. Die folgende Lisp-Code berechnet die Werte für einen 10 mm Fräser mit zwei Schneiden.

(let* ((vc 200)
       (d1 10)
       (z 2)
       (n (/ (* vc 1000) (* 3.14 d1)))
       (fz (cond ((< d1 5) 0.04)
                 ((< d1 9) 0.05)
                 (t 0.1)))
       (f (* n fz z)))
  (format "Drehzahl n: %.0f U/min  Vorschub f: %.0f mm/s" n (/ f 60)))
Man sollte also mit 6 - 7 Tausend Umdrehungen und 2 cm Vorschub pro Sekunde fräsen. Somit reicht eine einfache Bohrmaschine nicht aus, da die meist nur bis maximal 3 Tausend Umdrehungen drehen. Viele schaffen auch nur die Hälfte und selbst die QUADRILL DR von Festool schafft mit ihren vier Gängen nur maximal 4 Tausend Umdrehungen. Aber zumindest könnte man damit im unteren Ende der GIS-Empfehlung (vc = 125) mit 13 mm Vorschub pro Sekunde fräsen.

Bei Stahl sieht die Sache etwas anders aus.

(let* ((vc 50)
       (d1 10)
       (z 2)
       (n (/ (* vc 1000) (* 3.14 d1)))
       (fz (cond ((< d1 5) 0.02)
                 ((< d1 9) 0.03)
                 (t 0.06)))
       (f (* n fz z)))
  (format "Drehzahl n: %.0f U/min  Vorschub f: %.0f mm/s" n (/ f 60)))
Hier wären nur 1500 Umdrehungen für 3 mm Vorschub nötig. Allerdings ist fraglich, ob das Getriebe das Drehmoment wirklich aushalten würde. Ich denke eher nicht, da es ja eigentlich eine Bohrmaschine ist.

Fazit: zum Fräsen von Aluminum kann man sich mit einer relativ teuren Festool QUADRILL DR behelfen aber in den für weiches Aluminium optimalen Bereich kommt man damit nicht. Für das gleiche Geld bekommt man von Kress sowohl eine Bohrmaschine (650 BS QuiXS) als auch einen Fräser (800 FME).

Mittwoch, 9. Oktober 2013

Checked Exceptions vs Interfaces

So genannte "Checked Exceptions" sind Ausnahmen in Java, die auf jeden Fall vom Programmierer behandelt werden müssen. Tut er das nicht, wirft der Compiler einen Fehler und verweigert die Übersetzung. Am Konzept der Checked Exceptions gibt es reichlich Kritikpunkte. Java selbst versucht in dem entsprechenden Tutorial das Konzept zu verteidigen. Besonders pikant ist aber, dass das Konzept der Checked Exceptions in Widerspruch steht zu einem anderen Konzept von Java und zwar den "Interfaces". Bei einem Interface handelt es sich um eine abstrakte Spezifikation eines Verhaltens, das unabhängig von der Art der Implementation ist. Das Interface weiß also nichts darüber, wie es implementiert sein könnte. Somit kann das Interface auch nicht wissen, ob bei einer Implementation eine Ausnahme auftreten kann und wenn ja welche. Das wiederum bedeutet, dass ein Interface gar keine Ausnahmebehandlung vorsehen kann, da dem Interface gar nicht klar sein kann, welche Fehler bei der jeweiligen Implementation auftreten könnten.

Java definiert seit der Version 1.5 das Interface "Appendable". Dieses Interface spezifiziert den Vorgang des Anhängens einer Zeichenkette an ein Objekt mittels der Methode append. Merkwürdigerweise sind alle drei Varianten von append so definiert, dass sie eine IOException werfen können. Das wirft die Frage auf, woher das Interface weiß, dass bei seiner Implementation eine IOException auftreten kann, obwohl der Sinn eines Interfaces darin besteht, dies gar nicht wissen zu dürfen? Die Antwort liegt in der hellseherischen Fähigkeit dieses Interface. Bei der Definition des Interfaces ging man davon aus, dass es mal eine Implementation geben könne, die beim Vorgang des Anhängens eine IO-Operation ausführen müsste. Und genau das würde das Entstehen einer IOException ermöglichen. Wenn man also vom Konzept der Checked Exceptions nicht abrücken will, muss man das Interface so gestalten, dass alle theoretisch denkbaren Checked Exceptions vorhergesehen werden um sie im Interface definieren zu können. Ein derartiges Anliegen ist natürlich völliger Unsinn.

Ergebnis dieses konzeptionellen Widerspruchs ist, dass man das Interface Appendable mit eigenen Checked Exceptions, die die Designer von Java leider nicht vorhergesehen haben, gar nicht implementieren kann. Das wiederum bedeutet, dass man in einer Implementation von Appendable alle Checked Exceptions in Unchecked Exceptions umwandeln muss. Und das wirf dann die Frage auf: wozu das eigentlich? Insbesondere wenn man sich vor Augen führt, dass Appendable kein Einzelfall ist. Das Problem tritt in gleicher Weise beim Iterator auf. Und obwohl der Iterator schon seit Version 1.2 mit an Bord ist, war man damals immerhin so schlau, sich die Blöße mit der IOException gar nicht erst zu geben. Das Iterator-Interface definiert keine implementationsspezifischen Ausnahmen, obwohl natürlich sonnenklar ist, dass auch beim Iterieren IOExceptions auftreten können.

Am Ende stellt sich dann die Frage: auf was will man lieber verzichten: Interfaces oder Checked Exceptions? Ich für meinen Teil bin der Meinung, wer Checked Exceptions benutzt ist selber Schuld.

Freitag, 16. August 2013

Startpage als Standard-Suchmaschine in älterem Firefox

Unser aller Held Edward Snowden hat uns nahe gelegt, deutlich mehr Augenmerk auf Datenschutz und Datensicherheit zu legen. Für mich fängt das mit der Google-Suche an. Glücklicherweise gibt es einen Anbieter namens ixquick, der die Google-Suche anonymisiert und unter dem Namen Startpage anbietet. Um die Suchmaschine im Browser zu nutzen gibt es für Firefox eine Search-Engine-Definition.

Beruflich bin ich aber gezwungen eine ältere Firefox-Version zu nutzen. Die hat das Problem, dass die Suche über die URL-Eingabe unabhängig von der Suche über das Sucheingabefeld konfiguriert wird. Die Lösung für das Problem findet sich in der Knowledgebase von Startpage. Man muss lediglich auf der about:config-Seite die Option keyword.URL parametrisieren.

Trägt man dort den folgenden Wert ein, klappt die Suche auch über die URL-Zeile:

https://startpage.com/do/search?language=german&cat=web&query=

Freitag, 5. Juli 2013

instanceof in Java

Javas instanceof Operator ist nicht nur wahr für die Klasse der ein Objekt angehört sondern auch für sämtliche Elternklassen. Das folgende Beispiel
class instance
{
  static class A {}
  static class B extends A {}

  static<T> void println(T arg) { System.out.println(arg); }

  public static void main (String[] args)
  {
    A a = new A();
    B b = new B();
    A c = b;

    println (a instanceof A);
    println (a instanceof B);
    println (b instanceof A);
    println (b instanceof B);
    println (c instanceof A);
    println (c instanceof B);
  }
}
generiert die folgende Ausgabe:
$ javac -cp . -Xlint:unchecked instance.java && java instance
true
false
true
true
true
true
Lediglich Objekte der Elternklasse sind keine Instanz einer Kindklasse.

Donnerstag, 21. Februar 2013

Mit Emacs Make dort starten, wo Makefiles liegen

Java Programmierer neigen zu exzessiv sinnlosem inflationärem Gebrauch von Unterverzeichnissen. Es gehört zum guten Ton, dass man sich erst mal durch einen Dschungel an Unterverzeichnissen hangeln muss, bevor man die erste Zeile Code schreiben darf. Sun hat es ehemals den Grundstein für diese Unart gelegt, indem man gezwungen war jedes Package in ein eigenes Verzeichnis legen zu müssen. Das entwickelte sich zum Fluch als man auf die Idee kam, sämtliche Klassennamen mit Domänennamen zu prefixen. Und die Maven-Verwirrten haben sich jetzt zum Ziel gesetzt, den Vogel endgültig abzuschießen. Man achte auf die Struktur eines simplen Hello-World-Programms:

my-app
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- com
    |           `-- mycompany
    |               `-- app
    |                   `-- App.java
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- app
                        `-- AppTest.java

Das sind sage und schreibe 12 Verzeichnisse für 3 Dateien. Ich denke die nächste Major-Version von Maven sollte sich gemäß Moorschem Gesetz auf wenigsten 24 Verzeichnisse steigern. Getreu dem Maven-Leitspruch: Ceterum censeo inodes esse delendam.

Emacs-Benutzer, die mit dieser Anti-Information gequält werden, haben beim Entziffern der Kaiserlichen Botschaft in den Tiefen des Gesetzes das Problem, dass der Build-Vorgang nicht an der Stelle gestartet werden kann, an der die Datei liegt, die gerade editiert wird. Das zum Quellcode zugehörige Makefile oder vergleichbarer Pom-Schrott liegt typischerweise 12 bis 96 Verzeichnisse höher.

Die Lösung ist wie so oft im EmacsWiki zu finden. Dort kann man sich die Funktion upward-find-file klauen, die nach einer passenden Datei im gesamten Verzeichnisbaum sucht:

(defun upward-find-file (filename &optional startdir)
  "Move up directories until we find a certain filename. If we
  manage to find it, return the containing directory. Else if we
  get to the toplevel directory and still can't find it, return
  nil. Start at startdir or . if startdir not given"

  (let ((dirname (expand-file-name
    (if startdir startdir ".")))
 (found nil) ; found is set as a flag to leave loop if we find it
 (top nil))  ; top is set when we get
      ; to / so that we only check it once

    ; While we've neither been at the top last time nor have we found
    ; the file.
    (while (not (or found top))
      ; If we're at / set top flag.
      (if (string= (expand-file-name dirname) "/")
   (setq top t))
      
      ; Check for the file
      (if (file-exists-p (expand-file-name filename dirname))
   (setq found t)
 ; If not, move up a directory
 (setq dirname (expand-file-name ".." dirname))))
    ; return statement
    (if found (concat dirname "/") nil)))

Damit kann ein Wrapper der Compile-Funktion relativ einfach folgendermaßen definiert werden:

(defun compile-next-makefile ()
  ""
  (interactive)
  (let ((default-directory (or (upward-find-file "Makefile") ".")))
    (command-execute 'compile)))

Ich definiere mir dafür typischerweise das folgende Tastaturkürzel.

(global-set-key (kbd "C-c m") 'compile-next-makefile)

PS: Der Begriff Anti-Information ist übrigens nicht auf meinen Mist gewachsen. Den hat sich Max Landorff in "Der Regler" ausgedacht. Ich finde ihn recht passend für vieles was einem im Java-Umfeld über den Weg läuft.

Donnerstag, 14. Februar 2013

OpenLDAP Quickstart

Die Version 2.4 von OpenLDAP ist mit der Sense durch die bisherige Art das Programm zu konfigurieren gegangen. Während früher die Konfigurationsoptionen in der Datei slapd.conf lagen, liegen sie nun im Directory selber. Alle Änderungen gehen nur noch über eine LDIF-Datei, die ldapadd oder ldapmodify vorgeworfen wird. Das setzt voraus, dass der Slapd läuft. Wenn man Slapd derart verkonfiguriert, dass er nicht mehr startet, kann die fehlerhafte Konfiguration auch nicht mehr berichtigen. Es sei denn man editiert die internen cn=config-Dateien von Slapd, was man aber auf keinen Fall tun soll. Über Vor- und Nachteile dieses Ei-Huhn-Problems kann man streiten. Was aber wirklich albern ist, ist der Sachverhalt, dass die OpenLDAP-Quick-Start-Anleitung von der Konfigurationsumstellung leider noch nichts mitbekommen hat. Wenn es schnell gehen soll, ist also der alte Weg doch besser.

Wenn man der neuen reinen Lehre folgen möchte wird es komplizierter. Die folgenden Ausführungen beziehen sich auf eine Default-Installation des "openldap-servers"-Pakets eines Red Hat Enterprise Linux Servers in der Version 6.3.

Zuerst muss man die Nummer der Konfigurationsdatei finden, die Bestandteil des DN der Konfigurationsoptionen ist. Die Datei ist nämlich bereits durch die Paket-Installation angelegt worden.

# grep -l olcSuffix /etc/openldap/slapd.d/cn\=config/*
/etc/openldap/slapd.d/cn=config/cn=schema.ldif
/etc/openldap/slapd.d/cn=config/olcDatabase={2}bdb.ldif

In diesem Fall ist es '{2}bdb'. Mit Hilfe dieses Strings können nun die drei Werte gesetzt werden, die man minimaler Weise für einen Slapd setzten muss:

  • Base DN (olcSuffix)
  • Admin DN (olcRootDN)
  • Admin Passwort (olcRootPW)
Die entsprechende LDIF-Datei sieht folgendermaßen aus:

dn: olcDatabase={2}bdb,cn=config
changeType: modify
replace: olcSuffix
olcSuffix: 0=my-base

dn: olcDatabase={2}bdb,cn=config
changeType: modify
replace: olcRootDN
olcRootDN: cn=my-admin,o=my-base

dn: olcDatabase={2}bdb,cn=config
changeType: modify
replace: olcRootPW
olcRootPW: {SSHA}TAXHVcISg/XoRXTe2fSJFYpZTWYqix0t

Das Passwort erzeugt slappasswd:

# slappasswd
New password:
Re-enter new password:
{SSHA}TAXHVcISg/XoRXTe2fSJFYpZTWYqix0t

Die Datei wird mit ldapadd importiert:

# ldapadd -Y EXTERNAL -H ldapi:/// -f conf.ldif

Anschließend kann geprüft werden, ob die Anmeldung funktioniert, indem man sich mit dem Admin-Konto anmeldet:

# ldapsearch -x -D 'cn=my-admin,o=my-base' -W '(objectclass=*)'
Die Suche wird zwar kein Ergebnis liefern, weil im LDAP noch nichts enthalten ist, aber die Anmeldung mit dem neuen Passwort wird geprüft. Um sich mit JXplorer oder einem anderen Browser anzumelden, muss noch der Wurzelknoten definiert werden:
dn: o=my-base
objectclass: top
objectclass: organization
o: my-base
Der Import mit Hilfe des Manager-Kontos:
# ldapadd -x -D "cn=my-admin,o=my-base" -W -f top.ldif

Freitag, 1. Februar 2013

Netzwerkverschlüsselung für Oracle aktivieren

Oracle ist in der Lage die Netzwerkkommunikation auch ohne SSL und Zertifikate zu verschlüsseln. Dabei wird der Payload der TCP 1521-Verbindung verschlüsselt. Der Listener bekommt davon gar nichts mit und braucht auch nicht umkonfiguriert werden. Allerdings wird auf Client-Seite eine aktuelle Version des JDBC-Treibers benötigt. Das ojdbc14.jar funktioniert nicht. Man kann die Option mit dem Oracle Net Manager aktivieren:
Wichtig ist, dass der Encryption-Type auf "required" steht, da sonst auch unverschlüsselte Verbindungen zugelassen werden. Die Konfiguration steht anschließende in der sqlnet.ora-Datei:
SQLNET.ENCRYPTION_TYPES_SERVER= (AES256)
SQLNET.ENCRYPTION_SERVER = required

Sonntag, 13. Januar 2013

NODEADKEYS mal anders

Früher war alles einfach. Man nahm die X11-Konfigurationsdatei und aktivierte die Option. Heutzutage ist es ... eigentlich immer noch einfach. Man muss nur wissen wie es geht. Nur leider findet man es bekannter maßen mit dem Alter immer lästiger, sich neue Wege für alte Ziele zu merken. Deswegen steht es hier. In /etc/default/keyboard die folgende Zeile eintragen:
XKBVARIANT="nodeadkeys"
Und danach den folgenden Befehl aufrufen:
udevadm trigger --subsystem-match=input --action=change
Steht alles in der keyboard man page. Aber das ist schon wieder so einfach, dass man nicht darauf kommt.