seeseekey.net - Invictus Deus Ex Machina

Das Visual Studio formatiert den Quellcode automatisch nach den eingestellten Richtlinien. Wenn man nun aber die Richtlinien ändert, steht man vor dem Problem, das der Quelltext noch nach den alten Richtlinien formatiert ist.

Die Formatierungseinstellungen im Visual Studio

Leider gibt es keine direkte Option im Visual Studio um den bestehenden Quelltext am Stück neu zu formatieren. Allerdings kommt man mit einem kleinen Makro (abgeleitet vom VS Formater Macro) an dieser Stelle weiter. Dazu wird im Visual Studio die Package Manager Console (zu finden unter Tools -> NuGet Package Manager -> Package Manager Console) geöffnet und dort folgendes eingegeben:

function f($projectItems) { $projectItems | ? { $_.Name -ne $null -and $_.Name.EndsWith( ".cs" ) -and -not $_.Name.EndsWith( ".Designer.cs" ) } | % { $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}') ; $win.Activate() ; $DTE.ExecuteCommand('Edit.FormatDocument') } ; if ($projectItems) { $projectItems | % { f($_.projectItems) } } }
 
$dte.Solution.Projects | % { f($_.ProjectItems) }

Das Visual Studio öffnet nun alle *.cs Dateien in der geöffneten Solution und formatiert die Quelltexte neu. Dieser Vorgang ist dabei relativ langsam und führt bei größeren Projekten dazu das das Visual Studio einfriert. Auf Stack Overflow gibt es eine elegantere Lösung:

function FormatItems($projectItems) {
    $projectItems |
    % {
        # Write-Host "    Examining item: $($_.Name)";

        if ($_.Name -and $_.Name.ToLower().EndsWith(".cs") `
            -and (-not $_.Name.ToLower().Contains(".designer."))) {

            $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}');
            $win.Activate();

            $dte.ExecuteCommand('Edit.FormatDocument');

            if (!$_.Saved) {
                Write-Host "    Saving modified file: $($_.Name)";
                $dte.ExecuteCommand('File.SaveSelectedItems');
            }

            $dte.ExecuteCommand('Window.CloseDocumentWindow');
        }

        if ($_.ProjectItems -and ($_.ProjectItems.Count -gt 0)) {
            # Write-Host "    Opening sub-items of $($_.Name)";

            FormatItems($_.ProjectItems);
        }
    };
}

$dte.Solution.Projects | % {
    Write-Host "-- Project: $($_.Name)";

    FormatItems($_.ProjectItems)
}
;

Bei dieser Lösung wird jede Datei nach der Neuformatierung, gespeichert und wieder geschlossen. Leider wird auch diese Lösung von Datei zu Datei langsamer, so das sie für größere Projekte wiederrum unbrauchbar ist. Mit der Extension Format Document gibt es eine Lösung welche schnell genug ist, allerdings funktioniert diese nur unter Visual Studio 2010. Nach einigen Anpassungen habe ich eine Version gebaut, welche auch unter Visual Studio 2012 und 2013 läuft. Das Problem an dieser Variante ist, das Dateien in Ordnern leider nicht berücksichtigt werden. Alles in allem ist keine der vorgestellten Lösungen wirklich optimal, allerdings kann man viele Fälle mit den vorgestellten Lösungen lösen.

Da läuft der Webserver mit Nginx und PHP (eingebunden über den FastCGI Process Manager) seit vielen Wochen ohne Probleme und plötzlich wird man nur noch mit einem:

502 Bad Gateway

begrüßt. Das ist im ersten Moment verwunderlich, wenn sich nichts an der Konfiguration geändert hat. Dem Nutzer und gestressten Administrator möchte diese Meldung dabei mitteilen, das die Verbindung zum „PHP-Server“ nicht funktioniert. Wenn über ein Unixsocket auf das PHP zugegriffen wird, so kann es zur 502er Fehlermeldung kommen, wenn der Datei keine ausreichenden Rechte mehr zugewiesen sind. Mit einem beherzten:

chmod go+rw /var/run/php5-fpm.sock

verfügt das Socket wieder über die korrekten Zugriffsrechte. Unter Umständen muss die PHP-Engine mit:

service php5-fpm restart

neugestartet werden. Verursacht werden kann dieses Problem unter anderem durch automatisch eingespielte Updates, welche die Berechtigung der Socket-Datei verändern.

Vor ein paar Tagen ist mein erstes Buch Selfhosting — Server aufsetzen und betreiben erschienen. Das Buch dreht sich thematisch um das Hosting und dem Betrieb eines eigenen Servers und begleitet den Leser bei der Auswahl des passenden Anbieters, führt ihn in Linux als verwendetes Betriebssystem ein und begleitet ihn beim Aufsetzen konkreter Serverprojekte, wie das Aufsetzen von Mail-, Web– und anderen Serverdiensten. In den abschliessenden Kapiteln wird auf weitere wichtige Sachverhalte wie die Sicherheit und das Backup des eigenen Servers eingangen, so das der Leser einen guten Einblick in den Betrieb eines Servers gewinnt.

Erhältlich ist das Buch unter anderem bei Amazon, Beam, eBook.de, iTunes und Thalia. Im Buch selbst ist ein Code enthalten, mit welchem man zusätzlich zum gekauften Buch eine DRM freie Version beziehen kann.

Bei Icecast handelt es sich um einen freien Streamingserver. Der Server nimmt ein Signal entgegen und streamt es über einen Mountpoint, mit welchem sich die Nutzer des Servers verbinden um den Stream zu hören. Leider ist das Icecast-Protokoll nicht wirklich gut dokumentiert. Stattdessen wird darauf verwiesen, das der Quellcode verfügbar ist. Mit diesem Artikel soll diesem Problem ein wenig Abhilfe geschaffen werden. Das Icecast-Protokoll ist streng genommen einfaches HTTP. Wenn ein Eingangssignal zu einem Icecast-Server gestreamt sendet die Streamingquelle einen HTTP-Request (am Beispiel von butt):

PUT /stream123 HTTP/1.1
Authorization: Basic c291cmNlOmhhY2ttZQ==
User-Agent: butt 0.1.14
Content-Type: audio/mpeg
ice-name: no name
ice-public: 0
ice-audio-info: ice-bitrate=128;ice-channels=2;ice-samplerate=44100

Bei Mixxx würde dieser Request so aussehen:

SOURCE /stream123 HTTP/1.0
Authorization: Basic c291cmNlOmhhY2ttZQ==
User-Agent: libshout/2.0.0
Content-Type: application/ogg
ice-name: 
ice-public: 0
ice-url: http://www.mixxx.org
ice-genre: Live Mix
ice-audio-info: bitrate=128
ice-description:

Den SOURCE-Request den Mixxx hier anwendet ist seit der Version 2.4 des Icecast-Server veraltet und sollte nicht mehr genutzt werden. Stattdessen soll der PUT-Request verwendet werden. Wie man hier sehen kann erfolgt die Authentifizierung über das Basic Authentication Scheme (auch als HTTP Basic Authentication bekannt). In dem Request sind eine Reihe von ice-* Parametern zu finden:

ice-audio-info
Der Parameter ice-audio-info übermittelt eine Schlüssel-Wert-Liste von Audioinformationen. Die Parameter werden dabei durch ein Semikolon getrennt, das ganze könnte z.B. so aussehen:

channels=2;samplerate=48000;

Die Parameter müssen dabei mit der URL-Kodierung kodiert werden.

ice-bitrate
Der Parameter ice-bitrate setzt die Bitrate des Streams.

ice-description
Ist die Beschreibung des Streams nicht mit dem Tag stream-description definiert, so kann die Beschreibung über den Parameter ice-description eingestellt werden.

ice-genre
Ist das Genre des Streams nicht mit dem Tag genre definiert, so kann dies über den Parameter ice-genre eingestellt werden.

ice-name
Ist der Streamname nicht mit dem Tag stream-name definiert, so kann dies über den Parameter ice-name eingestellt werden.

ice-public
In der Konfiguration gibt es das Attribut public, welches angibt ob der Stream in einem öffentlichen Verzeichnis auftauchen soll. Ist der Public-Tag für den Mountpoint nicht definiert, kann dies über den Parameter ice-public gesetzt werden.

ice-url
Ist die URL des Streams nicht mit dem Tag stream-url definiert, so kann dies über den Parameter ice-url eingestellt werden.

Daneben gibt es noch den Content-Type welcher die Art des Streams definiert. Auf diesen Request antwortet der Icecast-Server (wenn die Authentifizierung korrekt ist) mit einem:

HTTP/1.0 200 OK

Statt dem Statuscode 200 sind noch eine Reihe weiteres Codes als Antwort möglich:

401 You need to authenticate
Die Authentifizierungsdaten sind nicht korrekt.

403 Content-type not supported
Streamformat wird von Icecast nicht unterstützt.

403 No Content-type given
Der Quellclient sendete kein Content-Type mit, dies wird allerdings zwingend benötigt.

403 internal format allocation problem
Internes Problem von Icecast mit dem gewählten Formatplugin.

403 too many sources connected
Das in der Konfiguration definierte Limit an gleichzeitig verbundenen Clients wurde überschritten.

403 Mountpoint in use
Der gewählte Mountpoint ist bereits in Benutzung.

500 Internal Server Error
Ein interner Fehler im Icecastserver, auf Clientseite gibt es für diesen Fehler keine Lösung.

Eine Besonderheit ist der Statuscode 100 (Continue) welcher gesendet wird, wenn der Client einen Request mit folgendem Inhalt gesendet hat:

Request: 100-continue

Mit dem Statuscode bestätigt der Server das der Client weiter Daten senden kann. Danach beginnt der Quellclient mit dem häppchenweisen senden des Ogg Vorbis– oder MP3-Stream — das bedeutet das eine MP3 nicht am Stück gesendet wird, sondern in Häppchen welche das Fortschreiten des Streams widerspiegeln. Beim Empfangen eines Streams passiert effektiv das selbe. Der Client (z.B. VLC) sendet dem Server einen GET-Request:

GET /stream123 HTTP/1.1
Host: 10.63.48.119:8000
User-Agent: VLC/2.2.1 LibVLC/2.2.1
Range: bytes=0-
Connection: close
Icy-MetaData: 1

Darauf antwortet der Icecast-Server mit mit:

HTTP/1.0 200 OK
Server: Icecast 2.4.0
Date: Thu, 02 Jul 2015 10:13:50 GMT
Content-Type: audio/ogg
Cache-Control: no-cache
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Pragma: no-cache
ice-audio-info: samplerate=44%2e100;channels=1;quality=0
icy-pub:1

Anschließend sendet der Icecast-Server die Audiodaten an den Client, welche dieser wiedergibt.

Mit dem Raspberry Pi kann man mit Hilfe von Icecast schnell einen Streamingserver für Audio installieren. Dazu muss im ersten Schritt Icecast installiert werden:

apt-get install icecast2

Während der Installation startet die Konfiguration des Paketes. So wird nach dem Hostnamen und den Passwörtern zum Streamen gefragt. Nach der Installation ist die Weboberfläche von Icecast unter Port 8000 und der entsprechenden IP erreichbar — in meinem Beispiel unter http://192.168.1.100:8000/. Der Standardnutzer für den administrativen Bereich ist dabei admin.

Die Weboberfläche von Icecast

Mit dieser Konfiguration ist der Raspberry Pi ein Streaming Server. Mit einem Tool wie butt, kann der Server nun bespielt (Standardnutzer: source, Passwort: hackme) werden. Die Mountpoints werden bei der Verbindung automatisch angelegt. Wenn man mit butt den Mountpoint stream123 bespielt, befindet sich der Stream in diesem Beispiel unter http://192.168.1.100:8000/stream123 und kann mit einem entsprechenden Player abgespielt werden.

Sim City sollte jedem der sich halbwegs für Spiele interessiert ein Begriff sein. Dabei handelt es sich um eine ursprünglich zweidimensionale Simulation einer Stadt. Das klassische Sim City wurde vor einigen Jahren in Form von Micropolis unter einer freien Lizenz veröffentlicht. Mit 3d.city wurde dieses Prinzip nun in die dritte Dimension und in den Browser befördert.

3d.city am Beispiel einer kleinen Stadt

Für die Simulation nutzt 3d.city die Javascript-Implementation micropolisJS bzw. baut darauf auf und nutzt für die 3D-Darstellung die three.js-Engine. Das Spiel ist unter der GPL lizenziert und damit freie Software. Der Quelltext ist auf GitHub zu finden. Ausprobiert werden kann 3d.city unter lo-th.github.io/3d.city/.

Im Internet gibt es eine Reihe von Diensten und Archiven, welche Snapshots von Webseiten speichern. Die bekanntesten dieser Dienste dürften Archive.org bzw. dessen Wayback-Machine und der Google Cache sein.

CachedView.com

Ist man nun auf der Suche nach einer bestimmten Webseite, so kann man die einzelnen Caches natürlich einzeln abklappern. Eleganter funktioniert dies mit CachedView — dort gibt man die gesuchte URL ein und durchsucht damit gleichzeitig den Google Cache, das Webarchiv von Archive.org und den Coral Cache. Zu Finden ist CachedView unter cachedview.com.

Wenn man von einem Mac zu einem anderen Mac umzieht, kann es vorkommen das bestimmte Passwörter sich noch in der Keychain des alten Mac befinden. Möchte man diese Passwörter übernehmen, so muss man die alte Keychain mit Hilfe der Schlüsselbundverwaltung einbinden.

Die Schlüsselbundverwaltung unter Mac OS X

Die Keychain befindet sich dabei im Pfad /Users/username/Library/Keychains/. Dort ist unter anderem eine Datei mit dem Namen login.keychain zu finden. In der Schlüsselbundverwaltung kann man diese keychain–Datei über den Menüpunkt Schlüsselbund hinzufügen laden. Die gewünschten Passwörter können nun in den Standardschlüsselbund des neuen Macs überführt werden. Zu berücksichtigen ist hierbei, das für jeden Datensatz das Passwort der eingebundenen Keychain eingegeben werden.

Möchte man seine im Firefox gespeicherten Passwörter in den Passwortmanager 1Password importieren, so müssen die Passwörter des Firefox im ersten Schritt exportiert werden. Dazu kann das Add-On Password Exporter genutzt werden.

Preis: Kostenlos

Nachdem das Add-On installiert wurde, können die Passwörter im Einstellungsdialog des Add-Ons in das CSV-Format exportiert werden. Die exportiere CSV ist dabei leider nicht kompatibel zu 1Password 4 und 5. Aus unerfindlichen Gründen wurden die Importfunktionen in diesen Versionen stark beschnitten. Stattdessen muss man hier zur Version 3 von 1Password greifen.

Der CSV-Importer von 1Password 3

Der CSV-Import der 3er Version ist wesentlich mächtiger — in diesen kann die erzeugte CSV-Datei geladen werden und die Felder können über einen Dialog zugewiesen werden und anschließend in den Passwortmanager überführt werden. Danach kann der Passwortspeicher in eine 1-Password-Austauschdatei exportiert werden, welche wiederum problemlos die aktuelle 1Passwort–Version importiert werden kann.