Author Archives: alex

SME Server

Gestern kurz vor Feierabend wurde ich in ein Gespräch über Trac verwickelt. Im Institut laufen die Projekt-Repositories und die entsprechenden Bugtracker auf einem Linux-System mit der Distribution SME Server. Wissensdurstig wie ich bin, hab ich mich mal umgeschaut. Im Hinterkopf hatte ich noch einen Artikel aus der c’t 4/07, wo das System nicht so schlecht weg kam. Mittlerweile ist Version 7.3 aktuell und die Hardware-Anforderungen sind relativ niedrig. Genau genommen handelt es sich bei dem System um direkte Konkurrenz zu eisfair, nur mit Weboberfläche.

Runterladen des Installations-Images per Bittorrent war kein Problem und Testrechner stehen hier genug rum. Die Wahl viel auf den 700er Duron mit den zwei 20 GB Festplatten. SME Server reißt sich auch gleich beide unter den Nagel und richtet ein RAID 1 drauf ein. Bei der Installation konnte man sich auf der zweiten Konsole daher schön /proc/mdstat anschauen und sehen wie er die Arrays synchronisierte. Das ist auf jeden Fall ein nettes und sinnvolles Feature. Der Installer beschwerte sich auch nicht, dass die Platten nicht exakt gleich groß waren. Das kann der neue Installer von eisXen bzw. eisfair-2 noch nicht – ich werde das mal anregen.

Nachdem alle Dateien auf die Kiste kopiert waren, kam der Rechner beim Reboot bis zum Einbinden der Swap-Partition und blieb dann hängen. Schluss, Ende, das war der Test von SME Server. Nächster Kandidat im bunten Distributions-Hopping: DesktopBSD

Schicke Grafiken aus Matlab in LaTeX

Ich arbeite mit LaTeX und ich arbeite mit Matlab. Bei meiner letzten Arbeit habe ich die Grafiken in Matlab einfach als .eps-Datei exportiert und unverändert in meine TeX-Dateien eingebunden. Das funktioniert problemlos, sieht aber nicht so schick aus, wie es könnte. Da ich für andere Grafiken das wunderbare Paket PGF und TikZ von Till Tantau benutze, habe ich heute Möglichkeiten ausgelotet wie man mit PGF Matlab-Grafiken schick machen könnte. Gründe dafür werden in der Doku von PGF genügend angeführt:

However, there are a number of reasons why you may wish to invest time and energy into mastering the PGF commands for creating plots:

  • Virtually all plots produced by »external programs« use different fonts from the one used in your document.
  • Even worse, formulas will look totally different, if they can be rendered at all.
  • Line width will usually be too large or too small.
  • Scaling effects upon inclusion can create a mismatch between sizes in the plot and sizes in the text.
  • The automatic grid generated by most programs is mostly distracting.
  • The automatic ticks generated by most programs are cryptic numerics. (Try adding a tick reading »π« at the right point.)
  • Most programs make it very easy to create »chart junk« in a most convenient fashion. All show, no content.
  • Arrows and plot marks will almost never match the arrows used in the rest of the document.

The above list is not exhaustive, unfortunately.

Neben PGF selbst gibt es das Paket pgfplots von Christian Feuersänger, das es leicht macht, einheitliche Plots zu erstellen und sogar logarithmische oder semi-logarithmische Achsen ermöglicht. Leider scheint man bei pgfplots im Gegensatz zu PGF selbst noch keine externen Dateien mit den zu plottenden Werten einbinden zu können. Das Skript matlab2pgfplots.m funktioniert leider nicht mit dem steinalten Matlab 6.1 hier im Institut, also habe ich noch nach weiteren Möglichkeiten gesucht.

Paul Wagenaar hat zwei interessante Tools geschrieben. Mathfig2pgf ist ebenfalls ein Matlab-Skript zur Umwandlung in PGF, funktioniert aber leider auch nicht mit Matlab 6.1. Das zweite Tool ist Eps2pgf und erinnert nicht von ungefähr an PSfrag. Beispiele für Ergebnisse von eps2pgf kann man sich auf fauskes.net ansehen.

Da ich nicht nur ein paar wenige Werte zu plotten habe, bin ich mir noch nicht sicher, welche Variante ich wählen werde. In Frage kommt außerdem noch die LowLevel-Variante mit PGF allein. Ein Beispiel wie man dort externe Datenquellen, z.B. den Output von gnuplot einbindet ist dokumentiert, allerdings muss man sich dann wieder Achsen etc. alles selbst bauen, also wird es wahrscheinlich die Variante mit eps2pgf werden, es sei denn pgfplots wird um die Funktion zur Nutzung externer Datenquellen erweitert. Kommt Zeit, kommt Rat, so dringend ist das Problem ja nicht.

Branches und Merges mit Subversion 1.5

Nachdem letzte Woche der RC 5 von Subversion 1.5 veröffentlicht wurde, beschreibt Ben Collins-Sussman heute in seinem Blog ganz kurz das Feature von Subversion 1.5, auf das viele warten. Subversion 1.5 behält selbst ein Auge auf Branches und Merges und macht das Arbeiten mit Branches damit um einiges leichter. Er demonstriert dies an einem beispielhaften Arbeitsablauf:

1. Make a branch for your experimental work:

$ svn cp trunkURL branchURL
$ svn switch branchURL

2. Work on the branch for a while:

# ...edit files
$ svn commit
# ...edit files
$ svn commit

3. Sync your branch with the trunk, so it doesn’t fall behind:

$ svn merge trunkURL
--- Merging r3452 through r3580 into '.':
U button.c
U integer.c

$ svn commit

4. Repeat the prior two steps until you’re done coding.
5. Merge your branch back into the trunk:

$ svn switch trunkURL
$ svn merge --reintegrate branchURL
--- Merging differences between repository URLs into '.':
U button.c
U integer.c

$ svn commit
6. Go have a beer, and live in fear of feature branches no more.

Wenn man bedenkt, wie aufwändig manuelles Merging bei Subversion vorher war, könnte das jetzt kaum einfacher sein. Man musste in den Commit-Messages die Revisionsnummern mitloggen und aufpassen auch ja die richtigen Sachen von einem Branch in den anderen zu tun. Jetzt brauch man sich um die Revisionsnummern nicht mehr kümmern, das wird alles wegfallen, super coole Sache!

Sicherheitslücken beim Studentenausweis der OvGU

Die Studenten der Otto-von-Guericke-Universität Magdeburg bekommen einen Studentenausweis mit RFID-Chip. Das ist schon seit einigen Jahren so und eigentlich sehr praktisch. Ähnlich wie bei der Geldkarte kann man Geld auf die Karte laden. Damit kann man in der Mensa und den Cafeterien des Studentenwerks sein Essen bezahlen, in der Bibliothek kopieren und sich an speziellen Automaten zurückmelden. Die drucken dann auch das neue Gültigkeitsdatum auf die Karte, so dass man bei den Magdeburger Verkehrsbetrieben stets einen gültigen Fahrausweis hat. Zusätzlich ist noch ein Strichcode vorn drauf, damit dient der Studentenausweis auch als Nutzerausweis der Bibliothek. Das System kommt von der Firma Intercard.

Vor einigen Monaten fiel mir auf, dass im Foyer der Mensa zwei kleine Automaten aufgestellt wurden, die den aktuellen Ladebetrag der Karte anzeigen. Diese Automaten sind im Gegensatz zu den Lesegeräten an den Kassen der Mensa sozusagen autark, nur ein Stromkabel ist angeschlossen. Der logische Schluss: der Geldbetrag ist direkt auf der Karte gespeichert. Die naheliegende Vermutung: wenn es gelänge, den RFID-Chip entsprechend zu manipulieren, ließe sich Guthaben erschleichen. Da ich kein gewiefter Hacker bin, blieb es bei einer Nachfrage beim Studentenwerk, wo man mir einerseits bestätigte, dass der Betrag tatsächlich auf der Karte gespeichert ist und andererseits versicherte, dass das System sicher sei und ich mich bei weiteren Fragen an den Hersteller wenden solle – habe ich nicht gemacht. Das ganze passierte wie gesagt im letzten Jahr.

Vor einigen Wochen nun erschien in der c’t 8/08 ein Artikel mit dem Titel »Chiptease – Verschlüsselungssystem eines führenden Bezahlkartensystems geknackt«. Das ganze las sich zunächst wie der jährliche Aprilscherz der Redaktion. Doch weit gefehlt, der eigentliche Aprilscherz war richtig absurd und relativ leicht zu enttarnen, dies hier hatte Hand und Fuß. Die Autoren hatten den RFID-Chip freigelegt und dann Layer für Layer abgeschliffen und abfotografiert, um aus der Halbleiterstruktur auf die Funktionsweise und damit die verwendete Verschlüsselungstechnik schließen zu können.

Eine kurze Recherche ergab, dass der untersuchte und millionenfach verbreitete Chip vom Typ »Mifare Classic« auch von Intercard eingesetzt wird. Die c’t verweist in ihrem Artikel auf eine Untersuchung des niederländischen OV-Chipkaart-Systems. Die Stellungnahme, die Intercard am 7.4.2008 veröffentlicht hat, liest sich recht interessant:

Zur Verschlüsselung der Systemdaten und -informationen wird der geheim gehaltene sogenannte CRYPTO1 Chiffrieralgorithmus eingesetzt, welcher nur mit speziellen NXP Bausteinen umgesetzt und verarbeitet werden kann. Diese Bausteine sind auch in den Mifare Lesemodulen eingebaut. Die Schlüssellänge beträgt 48 Bit, daraus ergeben sich über 280 Billionen Kombinationsmöglichkeiten.

Punkt 1: Security by Obscurity. Die erfolgreiche Kryptoanalyse hat wieder einmal gezeigt, dass dieses Konzept auf äußerst wackeligen Füßen steht. Punkt 2: Schlüssellänge. Mag das Mitte der 90er noch Stand der Technik gewesen sein, in »Kleiner Passwortgenerator in Perl« haben wir letztens erst Schlüssellängen diskutiert und 48 bit sind heutzutage lächerlich wenig. Intercard schreibt völlig zurecht:

Fazit
Die einfache Struktur der aufgedeckten Rechenregel, voraussagbare Zufallszahlen sowie
Zusammenhänge zwischen Karten-ID und Schlüssel lassen einen erfolgreichen Angriff auf
die Karte gewissermaßen recht einfach erscheinen.
Die Aussage “Verschlüsselungsalgorithmus Mifare Classic nachvollzogen” muss also
im Grundsatz als korrekt bewertet werden !

Die möglichen Gefahren sind klar. Da aber die Karte an der Uni hier, soweit ich weiß, nicht als Zugangskarte sondern nur als elektronische Geldbörse dient, ist dieser Punkt für mich am interessantesten. Im Hintergrund des Bezahlsystems wird ein sogenanntes Clearingsystem benutzt. Das bedeutet, dass sämtliche Transaktionen an Aufladeautomaten und Kassen geloggt und ausgewertet werden. Bei Unstimmigkeiten, die bei manipulierten oder geklonten Karten logischerweise auftreten, können die entsprechenden Karten anhand ihrer Seriennummer gesperrt werden. Insofern mache ich mir um meine Karte erstmal keine großen Sorgen, würde aber dennoch empfehlen keine allzu großen Beträge aufzuladen.

Nach einer Bestätigung der Schwächen des Kartensystems vom 19.3.2008 schreibt heise letzte Woche übrigens in »Aus für RFID-System Mifare Classic?«, dass auch das Nachfolgesystem Mifare Plus anfällig ist. Mehr und ausführliche Information zum Thema sowie den Vortrag zum Thema auf dem 24C3 findet man auf der Homepage von Karsten Nohl.

Eins noch, Intercard hatte in dem oben verlinkten PDF noch folgendes angekündigt:

Weitere Vorgehensweise
InterCard wird für seine Kunden sehr zeitnah (ca. 4 – 6 Wochen) eine Migrationsstrategie auf
eine neue Kartentechnologie ausarbeiten und vorstellen.

Wer da nähere Informationen in Bezug auf die OvGU hat, kann die gern an mich weiterleiten.

LIRC für eisfair – eine Episode voller Rückschläge

Wie man auf Pack-Eis sehen kann, betreue ich das Paket »LIRC« für Eisfair. Wie bei climm und GnuPG bin ich 2005 aus persönlicher Notwendigkeit heraus in diese Rolle gerutscht. Mein Heimserver war damals für das Abspielen meiner Musik verantwortlich und eine Infrarotfernbedienung ist da Gold wert. Wie so oft im OpenSource-Bereich brachte ich das Paket auf einen Stand, der meinen Anforderungen genügte und beließ es bei einer längeren Liste mit Ideen und ToDos, die im Prinzip seit 2005 auf ihre Umsetzung warten – andere Dinge waren halt wichtiger.

Nun wurde kürzlich ein neues Kernel-Paket für eisfair-1 veröffentlicht: ein gepatchter 2.4.35. Wir haben im Testteam lange getestet bis er im März der Öffentlichkeit zum Fraß vorgeworfen wurde. Ein neuer Kernel bedeutet aber auch, dass LIRC neu übersetzt werden muss, da es seine Treiber selbst mitbringt und Kernelmodule nunmal zur Kernelversion passen müssen. Es gab auch schon die eine oder andere Anfrage in der Newsgroup und ich beschäftige mich seit ein paar Tagen mit einer neuen Version des Pakets.

Zunächst steht das Kompilieren an. Ich konnte LIRC 0.8.2 für die eisfair-Kernel 2.4.26-1 und 2.4.35-wt1 jeweils in den Versionen mit und ohne Unterstützung für SMP übersetzen – für 2.4.26 mit der alten Build-Umgebung mit gcc 2.95.3 und für den 2.4.35 mit der zukünftigen Build-Umgebung mit gcc 3.4.6, die zur Zeit vom Testteam getestet wird. Das Übersetzen von LIRC artet schnell in Arbeit aus, weil es mit einem Lauf aus ./configure, make und make install nicht getan ist. Das muss für jede Kernel-Version und jeden gewünschten Treiber einzeln gemacht werden, es sei denn, man kompiliert gleich alle Treiber. Tut man dies nicht, ist noch mindestens ein Lauf mit der Option --with-driver=userspace nötig, damit LIRC auch in der Lage ist mit verschiedenen Treibern gestartet zu werden und nicht nur mit dem, für den es kompiliert wurden, wie z.B. serial.

Also wie gesagt, ich konnte LIRC für die Treiber serial und atiusb kompilieren – das sind die beiden, wo ich selbst Hardware zum Testen habe. Dank VMware waren auch die verschiedenen Kernel kein Problem, ich hab einfach für jeden eine neue virtuelle Maschine angelegt. Die anfängliche Euphorie, dass auch ein LIRC 0.7.1 mit den aus 0.8.2 gebauten Kernelmodulen für 2.4.35 läuft, wich dann der ersten Enttäuschung. Ich hatte zunächst die Version, die mit allen Treibern laufen soll, mit --with-driver=none kompiliert. Das funktionierte logischerweise nicht. Der erste herbe Rückschlag: LIRC 0.8.1, 0.8.2 und 0.8.3pre1 lassen sich mit der neuen eisfair-Buildumgebung und der korrekten Option --with-driver=userspace nicht übersetzen, wie man auf der Mailingliste von LIRC nachlesen kann.

Man kann dort ebenfalls nachlesen, dass ich versucht habe, die neueste Version aus dem CVS zu übersetzen, wo dieser Fehler bereits behoben ist. Leider macht mir da die Buildumgebung einen Strich durch die Rechnung. Das Skript ./configure liegt nicht im CVS, sondern wird mit den autotools (autoconf, automake usw.) erst noch selbst erzeugt. In der Theorie funktioniert das gut, in der Praxis tritt bei mir leider der gleiche Fehler auf, den ich vor einiger Zeit schon hatte, als ich climm aus dem SVN bauen wollte. Es wird ein unbrauchbares Skript erzeugt, dass nur eine wenig hilfreiche Meldung ausgibt. Wenn sich jemand gut mit autoconf auskennt und eine Idee hat, wo da das Problem liegt, möge sie sich dringend bei mir melden! Fazit jedenfalls: LIRC aus CVS ist für mich nicht möglich.

Heute erreichte mich dann über die Mailingsliste von LIRC die überraschende Nachricht, dass gerade die 0.8.3pre2 rausgegeben wurde. Der o.g. Fehler tritt nicht mehr auf, dafür ein neuer. LIRC lässt sich nicht mehr mit dem Treiber serial übersetzen, weil in der entsprechenden Quellcode-Datei eine Header-Datei aus den Kernelquellen nicht gefunden wird. Zumindest wird sie bei den 2.4er Kerneln nicht gefunden. Ein flüchtiger Blick in den Quellbaum eines 2.6er Kernels offenbarte, dass es dort zwei Dateien io.h gibt, eine in /usr/src/linux/include/linux und eine in /usr/src/linux/include/asm – beim 2.4er Kernel gibt es bloß letztere.

Auch dies habe ich auf der Mailingliste von LIRC gemeldet und warte erstmal ab. Es gibt nämlich mehrere Möglichkeiten jetzt:

  • ich warte ab, bis die nächste LIRC-Version veröffentlicht wird, mit der ich alles korrekt übersetzen kann
  • ich baue das allgemeine LIRC und die Treiber für atiusb aus der 0.8.3pre2 und die Treiber für serial aus der 0.8.2
  • ich kann durch wundersame Eingebung oder Hilfe von außen den Fehler in der Buildumgebung finden, so es denn tatsächlich einer in dieser ist, und die aktuelle Version aus dem CVS übersetzen
  • ich gehe in den Versionen soweit zurück, bis ich auf eine stoße, die ich komplett übersetzen kann, das wäre dann wahrscheinlich die 0.8.0
  • ich behebe den Fehler in 0.8.3pre2 selbst und übersetze dann meine modifizierte Version

Ehrlich gesagt, gefällt mir die erste Version bisher am besten, allerdings könnte das unter Umständen noch eine Weile dauern, je nachdem wie schnell die Entwickler von LIRC die nächste Version rausbringen. Module aus verschiedenen Versionen wollte ich eigentlich vermeiden, um mir nicht eine zusätzliche Fehlerquelle aufzureißen. Auch eine alte Version finde ich nicht so cool. Ob wir den potentiellen Fehler in der Buildumgebung schnell finden, ist auch ungewiss, bleibt also im Grunde noch die letzte Möglichkeit: ich stöber durch den C-Code und beheb den Fehler selbst – dazu hab ich keine Lust…

Falls sich also jemand fragt, warum die neue Version des LIRC-Pakets für eisfair so lange braucht, ich weise sämtliche Schuld von mir und schiebe es auf höhere Gewalt!

Wie funktioniert UTF-8?

Ines hat sich im Beitrag Flash: Umlaute in XML gewundert, wieso in Flash Sonderzeichen so komisch kodiert werden. Ich hätte es fast als Kommentar beantwortet, aber dann schien es mir sinnvoll zu sein, einen eigenen Beitrag zu schreiben. Hier mal zum Verständnis ein gekürzter Ausschnitt:

ä   >   %C3%A4

Warum Flash solch eine eigenartige hex-Interpretation der Umlaute benötigt, ist mir schleierhaft. Ich konnte es jedenfalls nicht anhand einer ASCII-Tabelle nachvollziehen.

Eigentlich macht Flash gar nichts komisches sondern eine reine Kodierung in UTF-8. Um das zu erklären, muss man etwas weiter ausholen. Früher gab es die »ASCII-Tabellen«. Ein Zeichen wurde als ein Byte kodiert, d.h. bei 256 Zeichen ist Schluss. Die Lösung bestand darin, dass es nicht nur eine ASCII-Tabelle gab, sondern viele für verschiedene Sprachen und Alphabete. Beispiele für solche sogenannten Codepages oder Zeichensätze sind cp1252 oder iso8859-15. Die ersten 127 Plätze der Tabelle waren immer gleich, man sprach von 7-Bit-ASCII, darunter fallen z.B. Ziffern und das normale lateinische Alphabet, Sonderzeichen wie das kleine ä wurden in der anderen Hälfte kodiert.

Diese vielen Codepages stellen natürlich eine erhebliche Einschränkung dar, deswegen wurde Unicode entwickelt. Die einfachste Variante wäre es, statt ein Byte pro Zeichen einfach mehrere zu nehmen, bei UTF-16 und UTF-32 wird das auch so gemacht. Für Texte mit einem geringen Zeichenvorrat ist das aber Verschwendung von Speicherplatz, immerhin konnte man auch in iso8859 ganze Texte abbilden, ohne dass einem Zeichen fehlen und die wären gegenüber einer Kodierung mit konstant zwei Byte pro Zeichen nur halb so groß.

Deswegen gibt es UTF-8. Der Trick ist nun, dass in UTF-8 Zeichen mit unterschiedlich vielen Bytes kodiert werden können – es gibt 1-Byte-, 2-Byte-, 3-Byte und 4-Byte-Zeichen. Öffnet man einen Texteditor, legt eine UTF-8-Datei an, schreibt das kleine ä hinein und betrachtet das Ergebnis dann in einem Hex-Editor, sieht man dass es sich um ein 2-Byte-Zeichen handelt: C34A.

Wieso kann man diesen Wert nun nicht einfach so in einer Unicode-Tabelle nachschlagen? Das liegt daran, dass man in einem Strom von Zeichen ja auch die 1-Byte von den 2-Byte-Zeichen (und natürlich von den noch längeren) unterscheiden können muss. Wenn ich Zeichen a mit 8 kodieren würde, b mit 9 und ß mit 89, woran sehe ich dann, ob es ab ist oder ß? Deswegen werden bei UTF-8 nie alle acht Bit eines Bytes zum Speichern des eigentlichen Inhalts verwendet.

Um das zu erklären hilft zunächst ein Blick auf eine Unicode-Tabelle, z.B. auf decodeunicode.org, diese Tabelle gibt es nämlich trotzdem. Dort hat jedes Zeichen eine Zahl zugeordnet. So können die gleichen Zeichen mit dem gleichen Platz in der Unicode-Tabelle in verschiedenen Kodierungen wie eben UTF-8 und UTF-16 kodiert werden.

Das kleine ä hat also in Unicode den Platz 00E4 in Hexadezimal, das entspricht 228 im Dezimalsystem. Als nächstes hilft ein Blick auf Wikipedia. Dort sieht man, dass es in UTF-8 spezielle Markerbits gibt. Ich zeige das mal anhand vom oben erwähnten C3A4:

1100 0011 1010 0100

Diese Bits zeigen an, dass es sich um ein 2-Byte-Zeichen handelt. Wenn ich diese Bits jetzt wegstreiche, bleibt folgendes übrig:

000 1110 0100

Die führenden Nullen noch weg und dann ist das hexadezimal wieder genau E4 und dezimal 228, also genau der Platz vom kleinen ä in der Unicode-Tabelle. Die Bits des E4 werden also zusammen mit dem, was ich oben Markerbits genannt habe, in die Zwei Byte des C3A4 gepackt. Bei Zeichen, die weiter hinten stehen in der Unicode-Tabelle, werden die entsprechenden Bits dann eben auf drei oder vier Bytes verteilt. Kurz und gut, sieht alles komisch aus, ist aber keine Hexerei.

happy

svnsync und relocate

Ich spiegel bei mir zu Haus ein paar Subversion-Repositories von Software, die mir sehr wichtig ist oder wo ich persönlich schon mal in den Quellcode geschaut oder auch mal einen Patch eingereicht habe. Das ganze geschieht mit svnsync und einem kleinen Shell-Skript, das per Cronjob alle acht Stunden läuft. In den letzten Tagen bekam ich Fehlermeldungen, dass ein Quell-Repository nicht mehr auffindbar war. Eine kurze Recherche ergab, dass der anonyme Zugriff per https eingestellt wurde und nur noch Zugriff per http möglich ist, was de facto einer anderen URL gleich kommt, quasi einem Umzug des Repos. Bei einer normalen Working Copy von Subversion hat man kein Problem, da macht man in einem solchen Fall

svn switch --relocate https://svn.quelle.foo/svn/trunk 
    http://svn.quelle.bar/svn/trunk

und fertig. Bei svnsync gestaltet sich das etwas schwieriger. Die URL des Quellrepos wird dort in den Properties der Revision 0 des Zielrepos gespeichert, so dass man bei der Synchronisation nur noch die Ziel-URL angibt. Ein “Relocate” muss dann durch eine Änderung des entsprechenden Properties geschehen, in meinem Fall sah das dann so (ähnlich) aus:

svn ps svn:sync-from-url --revprop -r 0 
    'http://svn.licq.org/svn' https://foo.local/svn/licq-mirror 
    --username syncuser --password syncpass

Man überschreibt also einfach die bisherige Quell-URL mit der neuen, das ist alles, danach einfach wie gewohnt

svnsync sync https://foo.local/svn/licq-mirror 
    --username syncuser --password syncpass

aufrufen und alles funktioniert wie vorher auch, nur eben mit neuer Quell-URL.

Probleme beim Upgrade von Debian Sid

Nachdem Tux ja schon in XOrg vs. Eclipse über Probleme beim normalen Ugrade von Debian Sid berichtet hat, könnte dies zu einer kleinen Artikelserie werden. Heute in diesem Kino: libdjvulibre21. Bei Debian gibt’s schon einen Bugreport und die Lösung hab ich in einem Wiki gefunden:

dpkg --purge libdjvulibre15

purge mit aptitude reichte nicht aus. Danach braucht’s nur noch das einfache aptitude safe-upgrade und alles ist wieder in Butter.

Grub auf mehreren Festplatten

Leute spielen mit Eisenbahnen, sammeln Briefmarken oder züchten Rosen. Ich probiere neue Betriebssysteme aus und pflege verschiedene Installationen für den einen oder anderen Zweck. In einem Testrechner sind hier drei Festplatten verbaut, alles alte Dinger, aber genug Platz für mehrere Betriebssysteme.

In diesem speziellen Fall sind auf der ersten Platte (80 GB) Windows 98 und XP installiert sowie ein Ubuntu und ein Eisfair-1. Auf der zweiten Platte (40 GB) residiert ganz allein ein Debian Etch als Host für Xen und last but not least ist auf der dritten Platte (4 GB) noch Platz für eine Beta-Version von Eisfair-2. Wäre nur die erste Platte eingebaut, hätte ich kein Problem. Ubuntu benutzt Grub und Grub erkennt bei der Installation andere Systeme. Ubuntu selbst und das Eisfair-1 von der ersten Platte starten ohne Probleme, Ubuntu hat die Hand auf dem Bootloader und aktualisiert bei Kernel-Updates seine eigenen Einträge. Die beiden Windosen lassen sich über chainloader ebenfalls problemlos booten.

Interessant wird es mit Betriebssystemen auf den anderen beiden Platten. Die bringen für gewöhnlich ihren eigenen Bootloader mit und verwalten die entsprechenden Einträge bei Kernel-Updates oder ähnlichem auch selbst. Der neue Eisfair-Installer schreibt sich in den MBR der Platte, wo das System landet, in dem Fall die dritte Platte hdc. Debian lässt einem da mehr Freiheit, aber in Frage kommen im Prinzip nur der MBR von der zweiten Platte (hdb) oder direkt die Bootpartition /dev/hdb1. Will ich die Systeme booten, kann ich natürlich die Namen, Orte und Optionen der Kernel von Hand bei jedem Update in die Grub-Konfiguration des Ubuntu auf hda eintragen, aber das ist mir ehrlich gesagt zu umständlich.

Die nächste Möglichkeit ist der bereits erwähnte chainloader. Ja, aber… der funktioniert nur, wenn z.B. Debian seinen Bootloader an den Anfang einer Partition und nicht in den MBR schreibt. Ich habe es nicht hinbekommen, mit dem chainloader sozusagen den MBR einer anderen Platte zu starten. Klar, ich könnte jedesmal ins BIOS und die Bootplatte umstellen, aber das ist mir dann auch zu umständlich.

Heute habe ich eine weitere Möglichkeit herausgefunden. Es ist aus dem Grub-Menü heraus möglich, eine andere Grub-Config zu laden. Anstatt eines langen Eintrags mit kernel usw. reicht dann folgendes:

title       hdb: Debian
configfile  (hd1,0)/grub/menu.lst

Trage ich das bei den zusätzlichen Systemen in die /boot/grub/menu.lst meines Ubuntu ein, kann ich ganz locker die menu.lst laden, die unter der Fuchtel des Debian auf der zweiten Platte steht. Umgekehrt geht’s natürlich auch, so dass ich munter hin und her springen kann, auch zu dem Grub vom Eisfair-2 oder zurück zum Debian-Bootmenü und von da wieder zum Bootmenü vom Ubuntu und wenn ich dann vom Umherspringen in meinen Grub-Menüs genug habe, boote ich einfach das System, das ich will.

Smilies für Foren auf eigenem Webspace

Internetforen gibt es wie Sand am Meer und es gibt ebenso viele Seiten, wo man Smilies finden kann, die man über die Forencodes oder HTML einbinden kann. Diese Seiten tauchen auf und verschwinden wieder, einige fordern sogar direkt dazu auf, die Smilies runterzuladen und auf den eigenen Webspace zu packen. Das ist nicht weiter schlimm, aber da liegen sie nun in den Untiefen in irgendeinem Unterordner der eigenen Domain. Will man einen Smiley verwenden, wühlt man sich lange durch Verzeichnisse und schreibt die URL des Bildchens zusammen mit den Forencodes mühsam von Hand zusammen.

Genauso ging es mir und daher hab ich mir ein Skript in PHP gebastelt, das mir nicht nur alle Smilies, die ich gesammelt habe, übersichtlich anzeigt, sondern auch gleich noch den Forencode mit der passenden URL dazu. Der brauch nur noch kopiert werden und schon hat man den eigenen besonders witzigen Smiley im Internetforum seiner Wahl eingefügt. Folgendes habe ich in ein Grundgerüst einer HTML-Seite eingefügt. Ich hab das einfach mal ein wenig getrennt hier, damit es sich leichter kommentieren lässt, später einfach wieder zusammenfügen…

<?php
$extcounter = 0;
function fileextension($filename)
{
    $pospunkt = strrpos($filename,".");
    return substr($filename, $pospunkt+1,
        strlen($filename) - $pospunkt);
}

function isimagefile($filename) {
    $extension = fileextension($filename);
    if( ($extension == "gif") OR
        ($extension == "jpg") OR
        ($extension == "jpeg") OR
        ($extension == "png") ) {
        return true;
    }
    else {
        return false;
    }
}

In den beiden Funktionen passiert erstmal nichts spannendes. Die erste gibt von einem Dateinamen die Erweiterung, also den Teil nach dem letzten Punkt zurück. Die zweite Funktion bekommt so ein Ergebnis vorgesetzt und gibt wahr oder falsch zurück, je nachdem ob es die Erweiterung einer Bilddatei ist oder nicht.

function echodir($path = ".")
{
    $counter = 1;
    global $extcounter;
    $dir = dir($path);
    while(false !== ($file = $dir->read())) {
        if(("." == $file) OR (".." == $file))
            continue;
        if(is_dir($path."/".$file)) {
            echo "<h2>$file</h2>n";
            echo "<p>n";
            echo "<table>n";
            echodir($path."/".$file);
            echo "</table>n";
            echo "</p>n";
        }
        else {
            if(isimagefile($file)) {
                if($counter%2) {
                    echo "<tr>n";
                }
                echo "<td><img src="".$path."/".$file.""/></td>";
                echo "<td>[img]http://www.lespocky.de/smilies/" .
                    substr($path,2,strlen($path)-2) .
                    "/".$file."[/img]</td>n";
                if(($counter+1)%2) {
                    echo "</tr>n";
                }
                $counter++;
                $extcounter++;
            }
        }
    }
    $dir->close();
}

Hier passiert das spannende. Vorweg sei gesagt, wie die Dateien organisiert sind. In dem Ordner, wo das Skript liegt, befinden sich keine Grafikdateien, sondern nur Ordner. In diesen Ordnern liegen dann direkt die Smilies. Tiefere Ordnerebenen gibt es nicht.

echodir() ist eine rekursiv aufgerufene Funktion. Wird kein Argument übergeben, so ist das aktuelle Verzeichnis zu durchsuchen. Da wird dann in der while-Schleife jeder Eintrag durchgegangen. Bei “.” und “..” passiert nix weiter, es geht zum nächsten Schleifendurchlauf. Dann passiert eine Unterscheidung, ob der Eintrag eine Datei oder ein weiteres Verzeichnis ist. Bei einem Verzeichnis wird eine neue Überschrift geschrieben und eine Tabelle begonnen. Die Smilies sollen in zwei Spalten angezeigt werden, damit nicht so viel Platz verschwendet wird. Nach Beginn der Tabelle, wird echodir selbst rekursiv aufgerufen.

In diesem Aufruf wird die Funktion wegen der oben erwähnten Organisation der Dateien, dann auch Dateien finden und diese dann zweispaltig eintragen. Um die Spalten zu erkennen und an den korrekten Stellen die tr-Tags zu öffnen und zu schließen, werden die Smilies in $counter mitgezählt und über den Modulo-Operator jeweils in linke oder rechte Spalte geschrieben. Ausgegeben wird nicht nur der Smilie selbst zum Angucken, sondern auch das fertige Foren-Tag zum Markieren und Kopieren.

Irgendwann gibt es dann keine Verzeichnisse und Dateien mehr zum lesen, alles Smilies sind ausgegeben und … ach ja, die Funktion ist ja erst definiert und erklärt, aufgerufen muss sie noch werden:

echodir();

echo "<hr /><p>Das waren ".$extcounter." Smilies..</p>n";

?>

Die letzte Zeile ist noch ein bisschen Spielerei als Abschluss. Da die ganze Auflistung von dem PHP-Skript übernommen werden, brauchen neue Smilies nur auf den Webspace kopiert werden, fertig.

happy