Author Archives: alex

echo echo echo

Der Netzwerkdienst echo ist laut allwissender Müllhalde im inetd implementiert. Muss man wissen. Und dann muss man noch wissen, wie der aktiviert wird, ist er per default logischerweise nicht. Unter Debian Wheezy mit dem inetd aus dem Paket openbsd-inetd fügt man an geeigneter Stelle folgende Zeile zu /etc/inetd.conf hinzu:

echo    stream  tcp     nowait  root    internal

Nicht mehr mein Betriebssystem

Gerade eben, Büro: Build-Umgebung für Mikrocontroller auf Embedded Device angeworfen. Dort holt ein selbst geschriebenes Perl-Skript die Versionsinformationen aus dem Mercurial und erzeugt daraus eine Datei version.h, die beim Build eingebunden ist, so dass eine Versionsnummer im fertigen Binary landet. Automatisch. Ging immer. Eben nicht.

Es hat mich eine halbe Stunde gekostet rauszufinden, dass nicht mehr wie üblich das von mir installierte Strawberry Perl aufgerufen wird, sondern ein von MinGW mitgeliefertes, dem (mindestens) ein Modul fehlt, welches in meinem Skript genutzt wird.

Abhilfe schaffte die Umsortierung der Einträge in einer der Variablen %PATH% in den Umgebungsvariablen, damit mein Perl vor dem von MinGW gefunden wird. Dass das zusätzliche Perl übrigens bei MinGW dabei war und nicht in einem der anderen Pfade versteckt war, war übrigens nur gut geraten. Vermutlich gibt es noch mehr Perl-Instanzen, die irgendwelche Software hier mitgebracht hat. Unter Windows muss ja jeder immer wieder extra seinen eigenen Scheiß mitbringen.

Mal sehen, an wieviel anderen Stellen das später knallt. Wer den entsprechenden Dialog in Windows XP sofort findet und bei der (unter Entwicklern) üblichen Anzahl von zweistelligen Einträgen auch noch ohne Copy’n’Paste in externen Editor bearbeitet, werfe den ersten Stein.

Bei Linux gibt es ein Perl und in $PATH stehen maximal 5 Ordner.

Links klicken in Icedove Mail

Debian Stable und aktuell Wheezy ist das System, was ich auf meinen Rechnern benutze und die Thunderbird-Variante Icedove ist da auf Version 17.x und damit gibt es ein Problem: Icedove hält sich so gar nicht an eine der üblichen Varianten um einzurichten welche Anwendung sich öffnen soll, wenn man einen Link anklickt, nicht an die KDE-Mechanisem (eigentlich logisch), nicht an die vom System und nicht mal an seine eigenen. Konkret muss man über preferences → advanced → general → config editor an die Innereien ran. In den Optionen network.protocol-handler.app.http[s] steht hier x-www-browser was üblicherweise ein symbolischer Link ist, der auf /etc/alternatives/x-www-browser zeigt und das bedeutet auf Debian-basierten Systemen, dass man das über

sudo update-alternatives --config  x-www-browser

einstellen kann. Bei mir steht das auf iceweasel, aber Icedove öffnete alle Links mit Google Chrome. :-(

Ich hatte das vor längerer Zeit mal auf der deutschen Debian User Mailingsliste gefragt, aber die passende Antwort da im Archiv zu finden, ist umständlich und ich stand jetzt auf einem anderen Rechner vor dem selben Problem und hab’s ohne im Archiv zu suchen dann genauso gemacht:

network.protocol-handler.warn-external.http[s]

hab ich dann auf true gesetzt und bekam dann einen Auswahldialog. Was ich da auswähle taucht dann in den Preferences unter attachments → incoming auf, wo es vorher jedoch nicht stand. WTF?!

Also ganz ehrlich, egal wer sich das ausgedacht hat bei den Entwicklern, den würde ich gern mal persönlich sprechen! *motz*

Link

meanwhile in Frankreich: Frankreich setzt auf freie Software an den Hochschulen

:-)

HowTo: DSL-Router loggt zu rsyslog auf Debian Wheezy

Gestern schrieb ich, wie ich mal eben schnell Daten sammle wie oft mein Router sich neu verbindet. So ganz elegant ist das nicht, weil es quasi am Router vorbei geschieht und der Router ja selbst am besten weiß, was er tut. Das vorliegende Modell kann den Output seines syslog an einen anderen Server schicken und da wertet man dann direkt die Logs aus, nur wie macht man das, wenn der Server ein rsyslog auf einem Debian Wheezy ist?

Zunächst aktiviert man mal die Funktion, dass der syslog überhaupt Nachrichten von anderen annehmen soll. Das passiert in /etc/rsyslog.conf und es sind die Zeilen auszukommentieren, die die entsprechenden Module laden.

# provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

# provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514

Ich hab der Einfachheit mal beide aktiviert, weil ich nicht wusste, was der Router probieren wird. Dann wollte ich, dass alle Logmeldungen des Routers in einer Datei landen und nicht zwischen die normalen Log-Dateien des Systems mit dem rsyslog geraten. Wichtig ist, dass hier rsyslog 5.8.11 arbeitet und daher die Änderungen an der Config-File-Syntax bei v6 und höher, die upstream in der Doku beschrieben sind, noch nicht gelten. Mit ein bisschen manpage, HowTo, Wiki und dergleichen lesen und etwas Rumprobieren, habe ich dann folgendes in die neu angelegte Datei /etc/rsyslog.d/remote.conf geschrieben:

$template PathWithHostName, "/var/log/remote/%HOSTNAME%.log"
:source, !isequal, "falbala"    -?PathWithHostName
& ~

Ich schmeiße quasi alles, was nicht vom loghost “falbala” kommt, auf dem der rsyslog läuft, in einen Unterordner remote und in nach dem Host getrennt, wo es herkommt. Jetzt muss ich nur noch ein paar Tage Daten sammeln und dann hab ich ein bisschen Statistik in der Hand, die hoffentlich ausreicht damit mein ISP eine sofortige Kündigung akzeptiert …

Nachtrag: Damit das Log nicht irgendwann überläuft, empfiehlt es sich auch noch logrotate anzupassen. Ich habe dazu /etc/logrotate.d/rsyslog als Beispiel für eine separate /etc/logrotate.d/rsyslog-custom genommen und das dort eingetragen:

/var/log/remote/*.log {
        rotate 4
        weekly
        missingok
        notifempty
        compress
        delaycompress
        sharedscripts
        postrotate
                invoke-rc.d rsyslog rotate > /dev/null
        endscript
}

Externe IPv4-Adressen sammeln

Im Beitrag online oder O₂ drüben in meinem privaten Blog habe ich mich bereits über meinen neuen DSL-Anschluss ausgelassen. Was ich dort nicht schrieb: die Leitung ist nicht nur langsam, sondern es bricht auch regelmäßig die Verbindung ab. Damit ich bei zukünftigen Auseinandersetzungen mit meinem Provider ein paar Daten in der Hand hab und um selbst mal zu sehen, wie oft sich der Router am Tag neu einwählt, habe ich jetzt einen Cronjob laufen, der alle 5 Minuten die von außen sichtbare IPv4-Adresse holt und erstmal in ein CSV-File speichert. Sieht so aus:

#!/bin/sh
UTCNOW=$(date -u +%s)
CURRENTIP=$(wget -q -O - checkip.dyndns.com | sed -e 's/^.*<body>\(.*\)<\/body>.*$/\1/' | cut -f2 -d: | tr -d [:space:])
echo "${UTCNOW},${CURRENTIP}"
exit 0

Und weil ich das praktisch finde, hab ich’s auch zu GitHub Gist getan.

alex

2013-06-13

Dieses Blog ist quasi umgezogen, man sieht nur nichts davon. ;-)

Genau genommen, haben wir es vom alten Server gerettet und in eine frische WordPress-Netzwerk-Installation verfrachtet, d.h. es gibt jetzt nur noch eine Installation für die vielen Blogs auf dem selben Server, das was früher WordPress MU hieß. Es ist noch Finetuning nötig, aber wenigstens der Text aller alten Beiträge ist wieder erreichbar. In diesem Sinne: bitte gehen Sie weiter, es gibt hier nichts zu sehen …

Hello world!

Welcome to antiblau wordpress network. This is your first post. Edit or delete it, then start blogging!

AT91Boot_DLL-API-Aaaaargh-Anfall

Atmel ist so nett für seine auf ARM basierenden Microcontroller eine Software mitzuliefern, mit der man den Controller sozusagen in Betrieb nehmen und den angeschlossen RAM und Flash testen und bespielen kann, nennt sich SAM-BA. Enthalten ist eine Bibliothek namens AT91Boot_DLL.dll, deren API ganz brauchbar dokumentiert ist. Sucht man noch ein wenig quer, stößt man auch auf AT91-ISP, wo es zwei Beispielprojekte gibt, wie man die Bibliothek in eigenen Projekten nutzen kann. Der Vorteil an der Bibliothek ist, dass man sich um die Verbindung zur ARM-CPU via USB oder serieller Schnittstelle keine Gedanken machen muss, man ruft einfach die Funktion AT91Boot_Scan() auf und lässt die DLL suchen. Das Code-Beispiel aus der Dokumentation sieht so aus:

CHAR *strConnectedDevices[5];
for (UINT i=0; i<5; i++)
    strConnectedDevices[i] = (CHAR *)malloc(100);
AT91Boot_Scan((char *)strConnectedDevices);

Beim Betrachten der Funktionsparameter hatte ich bereits letzte Woche den Verdacht, dass das mal krachen könnte, wenn man hier der Bibliothek gar nicht sagen kann, wie lang die Liste jetzt wirklich ist, die man da reinfüttert. Im Beispielprojekt umfasst die übrigens 10 Elemente und das änderte ich Freitag nachmittag noch auf 5. Funktionierte Freitag auch, so weit so schön.

Montag, also heute, stieg die Anwendung dann reproduzierbar mit einer Access Violation in der msvcrt.dll aus beim Aufruf dieser Funktion. Klassisch: »Es geht nicht mehr, ich hab aber nichts geändert.«

Etliche Flüche, Tests, Recherchen und dergleichen später stellte sich raus, dass ich doch was geändert hatte: ich hatte heute noch ein, zwei USB-Geräte mehr an meinen Rechner angeschlossen. Die Bibliothek sucht zuerst nach über USB angeschlossenen ARM-Prozessoren und scheint alle aktiven USB-Geräte durchzugehen, 5 Elemente in der Liste haben dann nicht mehr ausgereicht, flugs im Präprozessor-Makro den Wert erhöht und schon läuft das wieder ohne Absturz.

Den Rumpelstilzchentanz, den ich hier aufgeführt habe, weil die ihre API nicht sauber designen können und einen so zur Suche nach so dämlich subtilen Fehlern zwingen, möge sich bitte jeder selbst vorstellen! *motz*

Microsoft Visual C++ 6 und CMake

Warum man eine steinalte Entwicklungsumgebung mit einem modernen Build-System zusammen benutzen will, lässt sich nicht nur mit »Weil es geht!« begründen, es gibt sogar handfeste Argumente dafür, doch der Reihe nach.

Aus Gründen hab ich hier einige MFC-Projekte vorliegen, die in Visual Studio 6 entwickelt wurden, für das hier auch eine gültige Enterprise-Lizenz existiert. Bekommen habe ich Quellcode eines älteren Projekts ohne die Projektdateien. Neu zu entwickeln ist ein vergleichbares Programm und da Entwicklungsumgebung und KnowHow verfügbar sind, wird das neue Projekt eben auch in Visual Studio 6 entwickelt, die Programme laufen ja trotzdem.

Mit CMake füge ich dem Quellcode jetzt einfach die passenden Dateien mit dem Namen “CMakeList.txt” hinzu und lasse mir von CMake ein Projekt für VS6 erzeugen. Vorteil: ich brauche keine Projektdateien im Versionsverwaltungssystem ablegen, kann mir das auschecken wohin ich will und mein Quellcodebaum enthält nur das nötigste. De facto war ich so sogar in der Lage, das alte Projekt, wo mir die Projektdateien fehlten, mit CMake zu bauen und dem auf die Finger zu gucken. Soviel zum »warum«, es folgt jetzt das »wie« …

Zunächst mal sei gesagt, wenn schon Visual Studio 6, dann auch das letzte Service Pack installieren. Ist ein FAQ1 und das Service Pack gibt’s bei Microsoft.

Da ich hier eine MFC-Anwendung entwickeln will, also ein Tool mit GUI, reicht mir der reine Code nicht aus, sondern ist sind noch ressource files nötig. Bevor ich also später die Projektdateien mit CMake generieren lasse, erzeuge ich mit dem Assistenten von Visual Studio ein neues MFC-Projekt, in meinem Fall »Dialogfeldbasierend«:

MFC-Anwendungs-Assistent Dialogfeldbasierend

Den Rest des Assistenten klickt man nach eigenen Vorstellungen durch und dann kann man Visual Studio erstmal wieder schließen. Man hat jetzt einen Ordner vorliegen, in dem folgende Dateien liegen:

von VS6 erzeugte Dateien für ein neues MFC-Projekt

Davon kopieren wir jetzt den Ordner res und folgende Dateien an einen neuen Ort:

  • foo.aps
  • foo.clw
  • foo.cpp
  • foo.h
  • foo.rc
  • fooDlg.cpp
  • fooDlg.h
  • Resource.h
  • StdAfx.cpp
  • StdAfx.h

Das ist jetzt unser neuer Source-Ordner und dort wird nun eine Datei namens CMakeLists.txt angelegt. Fortgeschrittene CMake-Nutzer können das auch auf getrennte Unterordner für Programmcode, Header und externe Ressourcen aufteilen, spar ich mir hier mal und zeige nur wie das mit einer einzigen CMakeLists.txt aussehen kann:

project(foo)
cmake_minimum_required(VERSION 2.8)

find_package(MFC)

set(FOO-H
    foo.h
    fooDlg.h
    Resource.h
    StdAfx.h
)

set(FOO-RC
    foo.rc
)

set(FOO-SRC
    foo.cpp
    fooDlg.cpp
    StdAfx.cpp
)

add_definitions(-D_AFXDLL)
set(CMAKE_MFC_FLAG 2)
add_executable(${PROJECT_NAME} WIN32
    ${FOO-H}
    ${FOO-RC}
    ${FOO-SRC}
)

install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX})

Zu set(CMAKE_MFC_FLAG 2) bitte nochmal selbständig die Doku lesen und nicht verwirren lassen, die dort gezeigten Code-Abschnitte sind aus älteren Versionen vom Installer von CMake selbst kopiert. Wie eingangs angedeutet, machen wir jetzt einen Build außerhalb des Source-Verzeichnisses und rufen dazu das CMake-GUI auf:

CMake GUI für unser Mini-Projekt

Nach einem Klick auf Configure wird man nach dem Generator gefragt. Dort wählt man Visual Studio 6 aus der Liste und bestätigt. Ein weiterer Klick auf Generate erzeugt dann die Projektdateien im zuvor eingestellten Build-Ordner, alles oben im Screenshot zu sehen. Mit einem Doppelklick auf die Datei foo.dsw öffnet sich dann Visual Studio und man kann sein Projekt bauen. Schick auch, dass es gleich ein Unterprojekt gibt, was einem die Anwendung installiert. Theoretisch gibt’s auch noch CPack, womit man sich dann noch gleich einen Installer backen kann, aber das würde jetzt hier zu weit führen. ;-)

das von CMake erzeugte VC6-Projekt

Wenn das alles soweit schön kompiliert, kann man den Source-Ordner so nehmen wie er ist und in das Versionsverwaltungssystem seiner Wahl packen. Projektdateien für Visual Studio generiert sich dann jeder Entwickler selbst mit CMake. Bisschen umständlich ist das später beim Hinzufügen von neuen Dateien ins Projekt, weil man die CMakeLists.txt parallel pflegen muss, aber das ist es meiner Meinung nach wert.

  1. Visual Studio 6 Compiler : Freezing CMake Configuration []