Schlechte Bildqualität im Firefox

Seit geraumer Zeit hatte ich ein Problem mit der Darstellung von Bildern im Firefox. Diese sahen ziemlich pixelig und zerstört aus. Ein Kollege konnte das Problem beheben, indem er sein Profil weggeschmissen und ein neues erstellt hat. Das wollte ich aber nicht. Deswegen hab ich ewig gesucht und schließlich die verblüffend einfache Lösung gefunden:

Man gehe auf Ansicht –> Zoom –> und mache einen Haken bei „Nur Text Zoomen“

Und plötzlich sehen die ganzen Bilder nimmer so schlimm aus ;-). Zugegeben, das ist kein wirklicher Fehler, allerdings hat mich das eine ganze Weile geärgert, das ich es lieber mal hier hinschreibe, evtl. haben ja auch andere das Problem, die eine Webseite mal vergrößert und verkleinert haben.

Also, User zu dumm, aber trozdem hilfreich.

Wer UMTS nutzt, kann ein anderes Problem haben: Es gibt Proxys bei den Providern welche Grafiken komprimieren um Webseiten schneller Laden zu lassen, hier hilft oft das Drücken von CTRL-R oder das abschalten des Proxys. Hier kann euch google weiterhelfen.

Content Komprimierung mit mod_deflate und Apache 2

Warum soll ich meinen Content Komprimieren?

Hierfür gibt es einige Argumente:

  1. Verringerung der nötigen Bandbreite, Verkleinerung des Volumens der Seite
  2. Ggf. schneller Ladezeiten beim Nutzer
  3. Good Style ;-)

Tatsächlich ist es so, das heute viele Webseiten auf Komprimierung Ihrer Daten setzen, dies ist mit modernen CPUs und effektiven Modulen wie mod_deflate, selbst bei hochvolumigen Seiten, kein Problem mehr. Hiermit kann ohne großen Aufwand massiv Bandbreite gespart werden, da nahezu alle modernen Browser mit komprimierten Inhalten umgehen können. Nach meinen Erfahrungen kann man locker 10 bis 20% Traffic einsparen, aber auch hier ist das ganze natürlich abhängig von den lokalen Gegebenheiten.

Hier eine Beispielkonfiguration im Apache:

#Maximize Compression
DeflateCompressionLevel 9
<Location />
# Insert filter
SetOutputFilter DEFLATE

# Netscape 4.x has some problems…
BrowserMatch ^Mozilla/4 gzip-only-text/html

# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip

# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won’t work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

# Don’t compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary

# Make sure proxies don’t deliver the wrong content
Header append Vary User-Agent env=!dont-vary

</Location>

Mit dem Parameter „DeflateCompressionLevel“ setzt man, wie bei gzip auch, die Stärke der Kompression. 9 ist das Maximum und 1 das schwächste. Dies kann man je nach Serverleistung variieren, wobei das ganze mit mod_deflate ziemlich effizient ist und ich auch mit einem 9 nur einen sehr geringen Anstieg der Serverlast hatte (Server mit mehreren Million Zugriffen/Tag). Der Rest der Konfiguration ist 1 zu 1 aus dem Apache Handbuch kopiert und ich hatte bisher nie Probleme damit.


Date Wed, 20 Jan 2010 08:12:01 GMT
Content-Type text/html;charset=ISO-8859-15
Vary Accept-Encoding,User-Agent
Content-Encoding gzip
Content-Length 6389
Xonnection close

Hier seht Ihr nochmal wie das dann im Header, welchen Ihr mit Firebug oder ähnlichem sehen könnt, anschließend aussieht. Content-Encoding ist gzip, das Kompressionslevel kann man hier nicht sehen, dieses wird im Header nicht angegeben. Ihr könnt allerdings mal mit dem CompressionLevel Paramter rumspielen und euch dann die Content-Length anschauen.

Hier noch der Link zum Apache Manual

Expire Header mit mod_expire im Apache 2

Wozu Expire Header?

Oft kommt es vor, das man Daten über einen Webserver ausliefert, welche lange Zeit konsistent bleiben, Logos, bestimmte Grafiken etc. Wenn man solche Bestandteile auf seiner Webseite hat, sollte man diese mit einem Expire Header versehen. Der Expire Header bewirkt dabei, das die statischen Bestandteile der Seite bei (den meisten) Nutzern nur einmal heruntergeladen werden und bis zum Ende der Expiration im Cache des Browser gehalten werden. Besucht der Anwender innerhalb der Expiration Zeit die Webseite nochmals, werden die statischen Bestandteile aus dem lokalem Cache des Benutzers geladen und müssen somit nicht erneut heruntergeladen werden. Dies bietet zwei Vorteile, zum einen spart man damit Bandbreite und Datenvolumen zum anderen ist die Ausgabe aus dem Cache, des Browsers, in der Regel deutlich schneller als das Herunterladen des Contents. Bei der Verbreitung von Breitbandanschlüßen (zu mindestens in Europa) kommt dem Argument des schnelleren Seitenaufbaus oft mehr Bedeutung zu als der genutzten Bandbreite, wobei dies natürlich auch stark vom jeweiligen Angebot abhängt.

Hin und wieder hat man den Bedarf Expire Header von bestimmten Dateitypen zu setzen, entweder weil die dahinterliegende Applikation dies nicht richtig kann, oder weil statischer Content direkt über den Apache ausgeliefert werden soll. Hierzu kann man das Modul mod_expire des Apache’s verwenden.

Hier ein Beispiel:

#set expire header for the static directorys to 7 days
<Directory /img/>
ExpiresActive On
ExpiresDefault „access plus 7 days“
</Directory>

In diesem Beispiel wird ein Expire Header für von 7 Tagen (bei wirklich statischem Content zu kurz) auf das Verzeichnis /img gesetzt.

Sobald das Modul aktiv ist und erfolgreich Arbeitet, kann man sich z.B. mit Firebug anschauen ob die Änderungen erfolgreich waren:
Date Wed, 20 Jan 2010 07:22:58 GMT
Server Apache
Last-Modified Wed, 08 Oct 2008 08:36:30 GMT
Etag "eb039a-33-458b9d013df80"
Accept-Ranges bytes
Content-Length 51
Cache-Control max-age=604800
Expires Wed, 27 Jan 2010 07:22:58 GMT
Content-Type image/gif

Hier sieht man nun sehr schön wie im Header die entsprechenden Expire Informationen gesetzt werden.

Hierzu gehören sowohl das Feld „Last-Modified“, „Cache-Control“ und natürlich „Expires“.

Eine Ramdisk unter Linux erstellen und verwenden

Eine Ramdisk erstellen

Hier beschreibe ich wie man unter den gängigen Linux Distributionen eine Ramdisk erstellt. Das kann an vielen Stellen ganz nützlich sein.

Was ist eine Ramdisk?

Eine Ramdisk ist ein Teil des flüchtigen Arbeitsspeichers (RAM –> Random Access Memory), auf welchen man wie auf eine Festplatte zugreift. Großer Vorteil der Ramdisk ist, das diese erheblich schneller ist als eine Festplatte. Während man von modernen Festplatten bis ca. 150 MB/s lesen kann, kann dies bei einer Ramdisk leicht mit über 1 GB/s passieren. Großer Nachteil an einer Ramdisk ist, das der Inhalt in einem flüchtigen Speicher liegt und bei jedem Reboot oder bei jedem abschalten der Maschine verloren geht. D.h. die Ramdisk muss bei jedem starten neu „beladen“ werden bzw. durch temporären Inhalt versorgt werden.

Wie erstellt man eine Ramdisk

Ein Ramdisk kann man heute unter jeder aktuellen Linux Distribution erstellen. Der Support für Ramdisks ist im Kernel integriert. Ich beschreibe hier alle Schritte die nötig sind um eine Ramdisk zu erstellen und diese als „Plattenersatz“ zu verwenden.

Kerneloptionen konfigurieren

Zum Erstellen einer Ramdisk muss man dem Kernel eine Option mitgeben diese zu erstellen. Das tut man in der Regel in seinem Bootloader. Auf dem meisten gängigen Distributionen ist dies Grub. Die Konfigurationsdatei befindet sich bei den meisten Distributionen unter /boot/grub/menu.lst. In dieser ist der zu bootende Kernel aufgeführt und seine Parameter. Erkennen kann man das an dem vorgestelltem Wort kernel. Wir fügen an diese Zeile einfach den Parameter ramdisk_size=xxxxxx an, wobei xxxxxxx durch eine Anzahl 1024KB Blöcke ersetzt wird. D.h. wenn ich 10 Megabyte Ramdisk haben möchte setze ich den Wert auf 10 * 1024 = 10240. Damit erhalte ich eine 10 MB Ramdisk. 300 MB Ramdisk sind dann entsprechend 307200. Ein Beispiel einer Ramdisk mit 976,5625 MB .

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/sda2
#          initrd /initrd-version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-53.1.21.el5)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-53.1.21.el5 ro root=LABEL=/ ramdisk_size=1000000
        initrd /initrd-2.6.18-53.1.21.el5.img

Ist der Parameter hinzugefügt worden muss gebootet werden. Damit der Kernel die Option bei Starten auswerten kann. Im Anschluß an den boot Vorgang kann man sich mit dem Befehl dmesg das Log des Kernels anschauen und folgendes entdecken:

Diese Ausgabe kommt nicht bei jeder Distribution …

Kernel command line: ro root=LABEL=/ ramdisk_size=1000000

Diese Ausgabe sollte man aber immer sehen, die Zahlen beziehen sich auf das Beispiel mit der 976,5625 MB Ramdisk.

RAMDISK driver initialized: 16 RAM disks of 1000000K size 4096 blocksize

Das sagt uns das jetzt prinzipiell 16 RAM disks mit 1000000K große zur Verfügung stehen. Das ist ein bischen viel, weil 16 * 1000000 K = 15625 MB = 15.2587890625 GB. Zuviel für die meisten Rechner. Den Rechner den ich hier verwende hat auch nur 8 GB RAM. Also hätten wir ein Problem, da uns der RAM nicht reicht. Aber keine Angst, wir haben nun nur die Möglichkeit 16 Ramdisks in der größe verwendet, der Speicher wird erst dann verbraucht wenn wir diese auch tatsächlich nutzen. Ich benötige nur eine und hab damit noch genug ram frei.

Ramdisk nutzen

Nachdem wir nun erfolgreich die Ramdisk(s) initialisiert haben, können wir diese nun nutzen. Dazu müssen wir ein Dateisystem auf der Ramdisk erstellen, damit wir auch Dateien abspeichern können. Die Ramdisk steht uns unter einer Device Adresse zur Verfügung, ähnlich wie eine Festplatte. /dev/ram0 ist die erste Ramdisk in einem System /dev/ram1 die zweite und so weiter, in meinem Fall bis /dev/ram15, also die 16te Ramdisk. Ich brauche ja nur eine, nehme also die /dev/ram0. Auf dieser Ramdisk benötigen wir kein tolles Filesystem mit Journaling oder ähnlichem, da es sowieso bei jedem booten verloren geht. Also entscheide ich mich für das klassiche ext2 Dateisystem, dies ist recht ausgereift und auf ner Ramdisk ausreichend performant. Wir verwenden also folgenden Befehl: mkfs.ext2 -m /dev/ram0. Damit erstellen wir das Dateisystem auf dem Device /dev/ram0, die Option -m bewirkt das wir das Dateisystem im vollen Umfang nutzen können und kein Platz für den Benutzer root reserviert wird (weil das brauchen wir hier ja nicht). Und schon ist unsere Ramdisk fertig. Wir können Sie nun mounten und verwenden. mount /dev/ram0 /mnt.

Zu Beachten

  • Die Erzeugung des Filesystems und das mounten muss nach jedem reboot wiederholt werden. Ich verwende dafür ein init script, mann kann es natürlich auch anders machen.
  • Auch zu beachten ist, das man jetzt eine hochperformante Platte hat, von der Daten schnell gelesen und in die Daten schnell geschrieben werden können. Es kann durchaus dazu kommen, das Prozesse die zuvor an zu langsamen Platten gescheitert sind, nun plötzlich an nicht ausreichender Prozessorperformance scheitern, bzw. den Rechner enorm auslasten. Das muss man im Einzelfall testen.

Init Scripte für Centos / Redhat fit machen (Chkconfig)

Init Scripte für Chkconfig

Hier bekommst Du eine kurze beschreibung wie man init Scripte für chkconfig fit macht.

Die Syntax

Für chkconfig sind folgende zwei Einträge im Init Script nötig:

  • chkconfig:
  • description:

Die description ist zwingend notwendig. Ein bischen Doku kann man schon machen.

Bei chkconfig: ist zu beachten, das man den “:“ nicht vergisst, ansonsten erkennt chkconfig den Eintrag nicht. chkconfig: hat drei Paramater, das Runlevel, die Startpriorität und die Stoppriorität. Der Runlevel besagt in welchem Runlevel der Dienst gestartet wird, also 1,2,3,4 oder 5. Die Angabe wird einfach durch die Angabe der Runlevel geamacht. Also:

chkconfig: 12345  <- Script wird in Runlevel 1,2,3,4 und 5 gestartet
chkconfig: 345 <- Übliche Variante, Script wird in Runlevel 2,4,5 gestartet

Die Startpriorität legt fest wann ein Script in den Runleveln gestartet wird. Also:

Script 1:
chkconfig: 345 20 <- Script wird in Runlevel 3,4,5 gestartet mit der Prio 20

Script 2:
chkconfig: 345 21 <- Script wird in Runlevel 3,4,5 gestartet mit der Prio 21 also später als Script 1

Die Stopprorität legt fest wann ein Script in den Runleveln gestopt wird. Also:

Script 1:
chkconfig: 345 20 80 <- Script wird in Runlevel 3,4,5 gestartet mit der Prio 20, gestopped mit der Prio 80

Script 2:
chkconfig: 345 21 79 <- Script wird in Runlevel 3,4,5 gestartet mit der Prio 21 also später als Script 1, gestopped wird es mit Prio 79 also früher als Script 1

Alles ganz einfach.

Eine Description sieht dann folgendermaßen aus:

description: Was mein Script macht

Auch nicht der Hammer. Hier sei nochmals gesagt, man braucht die description gelle Martin?

Beispiel

Hier nochmal ein komplettes Beispiel:

#! /bin/sh
#
# Mein Script
#
# chkconfig: 345 21 79
# description: Mein Script

[Howto/Tutorial] Dropbear ssh für Android cyanogenmod konfigurieren

Du möchtest also per ssh auf dein Telefon. Das ist prinzipiell ab der Version 4.0.2 der cyanogenmod Software auf deinem Telefon möglich. Ab dieser Version ist der dropbear ssh server mit dabei. Dieser nutzt im Build von cyanogen das Verzeichnis /data/dropbear/.

Du musst nun folgendes tun:

Einen ssh key mit PuTTY oder Linux erzeugen. Für Putty gibts hier eine Anleitung.

Jetzt muss Du den ssh public key als Datei speichern und authorized_keys Datei auf der sdkarte speichern.

Jetzt kommen die Sachen im Terminal deines Telefons:

Werde root:

su - 

Lege das Verzeichnis /data/dropbear und /data/dropbear/.ssh an:

mkdir -p /data/dropbear/.ssh  

Kopiere die die Datei authorized_keys nach /data/dropbear/.ssh

cp /sdcard/authorized_keys /data/dropbear/.ssh/

Setze nun die richtigen Rechte:

chmod -R 644 /data/dropbear

Erzeuge nun einen passenden Hostkey (das kann einen moment dauern):

dropbearkey -t rsa -f /data/dropbear/dropbear_rsa_hostkey

Optional kannst Du noch einen dss key erzeugen:

dropbearkey -t dss -f /data/dropbear/dropbear_dss_host_key

Jetzt musst Du Dir noch ein passendes Profil anlegen:

echo >>/data/dropbear/.profile "PATH=/usr/bin:/usr/sbin:/bin:/sbin \
:/system/sbin:/system/bin:/system/xbin:/system/xbin/bb:/data/local/bin"

echo >>/data/dropbear/.profile "export PATH"

Fertig!

Jetzt kannst Du den dropbear Server das erste mal starten:

dropbear -v -F

Wenn alles gut ist siehst Du folgendes (oder so ähnlich):

TRACE: enter loadhostkeys
TRACE: enter buf_get_priv_key
TRACE: enter rsa_key_free
TRACE: leave rsa_key_free: key == NULL
TRACE: enter buf_get_rsa_priv_key
TRACE: enter buf_get_rsa_pub_key
TRACE: leave buf_get_rsa_pub_key: success
TRACE: leave buf_get_rsa_priv_key
TRACE: leave buf_get_priv_key
TRACE: enter buf_get_priv_key
TRACE: enter dsa_key_free
TRACE: enter dsa_key_free: key == NULL
TRACE: enter buf_get_dss_pub_key
TRACE: leave buf_get_dss_pub_key: success
TRACE: leave buf_get_priv_key
TRACE: leave loadhostkeys
[6343] Sep 18 11:53:35 Not forking
TRACE: listensockets: 1 to try
TRACE: listening on ':22'
TRACE: enter dropbear_listen
TRACE: dropbear_listen: all interfaces
TRACE: leave dropbear_listen: success, 1 socks bound

Nun kannst Du das erste mal ein ssh auf dein Telefon machen. In einem anderen Artikel beschreibe ich wie man den Dienst beim booten startet. Hattest Du nun die Hoffnung auf ein Login unterwegs möglich ist, muss ich dich leider, zumindestens für T-Mobile, entäuschen. Du bekommst im T-Mobile Netz keine öffentliche IP, sondern eine Private (NAT). Damit ist es nicht möglich von aussen auf dein Telefon zuzugreifen.

Ein Teil dieses Artikels ist im übrigen dem Wiki hier entnommen.

Android SDK (DDMS) unter MAC OS X 10.6 Snow Leopard

Nach einem Update auf Snow Leopard musste ich Feststellen, das mein Android SDK nicht mehr so wollte wie ich.

>ddms
45:16 E/ddms: shutting down due to uncaught exception
45:16 E/ddms: java.lang.UnsatisfiedLinkError: /Users/tw/Desktop/eclipse/android-sdk-mac_x86-1.5_r3/tools/lib/libswt-pi-carbon-3236.jnilib:  no suitable image found.  Did find:  /Users/tw/Desktop/eclipse/android-sdk-mac_x86-1.5_r3/tools/lib/libswt-pi-carbon-3236.jnilib: no matching architecture in universal wrapper
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1878)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1771)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1045)
at org.eclipse.swt.internal.Library.loadLibrary(Library.java:123)
at org.eclipse.swt.internal.carbon.OS.<clinit>(OS.java:20)
at org.eclipse.swt.widgets.Display.createDisplay(Display.java:943)
at org.eclipse.swt.widgets.Display.create(Display.java:923)
at org.eclipse.swt.graphics.Device.<init>(Device.java:118)
at org.eclipse.swt.widgets.Display.<init>(Display.java:754)
at org.eclipse.swt.widgets.Display.<init>(Display.java:745)
at com.android.ddms.UIThread.runUI(UIThread.java:330)
at com.android.ddms.Main.main(Main.java:97)

Das liegt daran, das seit Snow Leopard Java in normalerweise mit der 64 Virtual Maschine von Java gestartet wird. In diesem Fall kann DDMS aber nur mit der 32 Bit Version. Die Lösung ist ganz einfach, edietiere die Datei android-sdk-mac_x86-1.5_r3/tools/ddms und ändere folgendes:

[cc lang=“bash“]

if [ `uname` = „Darwin“ ]; then
os_opts=“-XstartOnFirstThread“

[/cc]

auf

[cc lang=“bash“]

if [ `uname` = „Darwin“ ]; then
os_opts=“-XstartOnFirstThread -d32″

[/cc]

und schon läuft die Sache wieder rund.

Snow Leopard OS X 10.6 GUID Update Problem

Heute habe ich mein Snow Leopard erhalten. Nach einem Time Machine Full-Backup wollte ich dann mal loslegen und den Schnee Leoparden installieren. Alle Anwendungen geschlossen, DVD eingelegt und gewartet. Anschließen die DVD geöffnet und „Mac OS X Installation“ angewählt. „Fortfahren“ und „Akzeptieren“ geklickt und schon stutzig geworden. Warum prankt an meinem Volume ein kleines gelbes Ausrufungszeichen? Volume angewählt und folgendes gelesen:

„tw“ kann nicht verwendet werden, da die GUID-Partitionstabelle nicht verwendet wird.

Ändern Sie mithilfe des Festplatten-Dienstprogramms das P

artitionsschema. Wählen Sie das

Volume, klicken Sie auf den Titel „Partition“, wählen Sie das Volume-Schema und klicken Sie auf „Optionen“.

Installationsfenster von Snow Leopard

Installationsfenster von Snow Leopard

Was war passiert? Ich hatte letztens einen Plattencrash und eine neue Platte eigebaut. Diese auf die schnelle Partitioniert und auf das Volume mein Time Machine Backup restored. Dabei scheine ich irgendwas falsch gemacht zu haben. Ergo muss ich meine MacBook jetzt direkt von der CD starten (Das Festplattendienstprogramm im laufenden System bringt euch hier nix.). Also, CD rein, Rechner ausschalten und direkt nach dem einschalten die „C“ Taste gedrückt halten. Das ganze dauert eine halbe ewigkeit, doch dann startet das Installationsprogramm von der CD.

Das gleiche Spiel zeigt sich auch nach dem Starten con CD. Also, wählen wir mal hier von der CD „Dienstprogamme“ und „Festplatten-Dienstprogramm …“. Hier wähl ich jetzt mein Volume aus, und stelle fest das auch da nix geht. Was ein Dreck! Da steht nur ganze nett:

„Diese Partition kann nicht geändert werden.“

So manchmal könnte man ja kotzen, die Partition wurde mit dem Festplatten Dienstprogramm einfach angelegt. Also muss ich wohl damit leben alle meine Daten zu grillen, eine neue Partition mit einer GUID Tabelle anzulegen (geht unter Optionen beim Volume Schema). Mein Backup zurückspielen, und dann updaten.

Ich wünsche euch mehr Glück!

UPDATE: Nach der Neupartitionirung mit einer GUID Partition und einem restore meines Time Machine Backups, klappt das Update jetzt. Ich habe dabei noch Festgestellt, das ein Restore von der 10.6 Snow Leopard DVD erheblich schneller geht als von der 10.5 (5 zu 3 Stunden).

Solitaire

Heute und in Zunkunft will ich hier mal alle Android Apps vorstellen, die mir so über den Weg laufen. Aufgrund der späten Stunde habe mich mir was recht einfaches Ausgesucht. Die Applikation Solitaire.

Diese App vereint auf recht einfache Weise die Kartenspiele „Solitair“, „Spider“, „Freecell“ und „Forty Thieves“ in einer App. Die Bedienung aller Spiele ist gleich, Ihr könnt mit der Finger die Karten ziehen und loslassen, mit einem Klick auf den Stapel eine neue Karte ziehen (oder drei) und mit der Back Taste eure letzten Taten ungeschehen machen.

Hier habe ich einige Screenshots für euch vorbereitet. Das Spiel läuft im übrigen nur im Querformat.

Das Menü:

Das Menu der Solitair App

Das Menu der Solitair App

Im Menu habt Ihr wie hier zu sehen, die Möglichkeit ein neues Spiel zu starten, das Spiel in dem Ihr grad seit neu zu starten, Optionen zum Spiel zu verändern, zu Speichern und zu Beenden oder eingach gleich zu Beenden, ohne zu Speichern.

Wählt Ihr ein neues Spiel habt Ihr wie oben schon gesagt vier Stück zur Auswahl:

Android App Solitair Spieleauswahl

Android App Solitair Spieleauswahl

Die einzelnen verfügbaren Spiele möchte ich auch gerne zeigen:

Solitair:

Die Solitair App - Das Spiel Solitair

Die Solitair App - Das Spiel Solitair

Spider:

Die App Solitair - Das Spiel Spider

Die App Solitair - Das Spiel Spider

Freecell:

Die App Solitair - Das Spiel Freecell

Die App Solitair - Das Spiel Freecell

Forty Thieves:

Die Solitair App - Das Spiel Forty Thieves

Die Solitair App - Das Spiel Forty Thieves

Alles in allem gefällt mir die App sehr gut, läut stabil ist einfach und gut bedienen und hat den ganz klassischen charme des Windows Solitairs.

Netcat

Netcat ist ein sehr nützliches Tool für viele Gelegenheiten. Ich persönlich benutze es meistens nur um den Durchsatz eines Netzwerkes zu testen wenn ich mir nicht sicher bin ob Performanceprobleme auf das Netwzerk, oder die Software zurückzuführen sind.

Dazu muss man auf dem Zielrechner netcat (oft auch nc) starten:

netcat -l <Port> > <Dateiname>

Und natürlich auf der sendenden Maschiene ein entsprechendes Netcat starten damit auf dem Zielhost empfangen werden kann:

netcat <Zieladresse> <Port> < <Dateiname>

Wenn man die Zeit des des Befehl auf der sendenden Maschine misst, kann man daraus den Durchsatz errechnen, dieser kommt meist nahe der praktischen Leistungsgrenzen der Netzwerkverbindung, da dort weder Kompression noch aufwändige Protokolle overhead erzeugen.

Backup mit Netcat

Weiterhin kann man ganz nette Backups mit Netcat machen. Z.b. ganze Partitionen, oder ganze Platten. Partitionen kann man hinterher schön mounten, deswegen finde ich das praktischer. Will man eine Partition mit netcat über das Netzwerk wegsichern, macht man folgendes:

Auf dem Quellrechner:

dd if=/dev/<partition> | netcat/nc <Zieladresse> <Port> 

Auf dem Zielrechner:

netcat/nc -l <Port> > <Dateiname>

Und schon hat man ein file in dem die Partion enthalten ist. Diese kann man nun ein bischen aufpeppen.

Backup mit Tricks

Will man das ganze noch ein bischen verfeineren, schribt man bevor man ein solches Backup macht erstmal den restlichen space mit „0“ voll. Das geht ganz einfach mit:

cd <Verzeichnis auf der Partition>
dd if=/dev/zero of=lala.txt

Das hat den Sinn, das der freie Platz mit nullen überschrieben wird und sich so besser komprimieren läßt.

Aufpassen muss man bei der root Partition, da muss man ein wenig Platz freilassen. Das kann man mit der Angabe bs=1m und count=<mb frei – 50>. So vermeidet man das das System unansprechbar wird.

Anschließend komprimieren wir die Ausgabe des dd durch folgende Angabe:

Quellrechner:

dd if=/dev/<Partition> | gzip -9 -c | netcat <Zieladresse> <Port>

Damit wird das ganze dann „on the fly“ komprimiert. Das kostet zwar CPU Zeit, spart aber viel Platz. Auf dem Zielsystem braucht man eigentlich nicht viel ändern, ich würde als Endung einfach .gz anfügen, damit man weiß das das Image komprimiert ist.